Version Description
- Added compatibility with the "Add Meta Tags" plugin. The "Add Meta Tags" plugin is a popular tool to set SEO meta tags on site pages. Previously it rewrote the titles and description that Ecwid generated for search engines on your site. It's now fixed so if you use the plugin, everything should work fine and Google will index your products pages properly.
- Fixed a problem in the recently viewed products widget caused by Autoptimize plugin. Previously, if Autoptimize plugin is used on the site, the recently viewed products widget reset the displayed products when page reloads. We fixed that.
- A few internal improvements to make the plugin more stable and ready for the upcoming cool features. Stay tuned! More updates are coming.
Download this release
Release Info
Developer | Ecwid |
Plugin | Ecwid Ecommerce Shopping Cart |
Version | 3.4.4 |
Comparing to | |
See all releases |
Code changes from version 3.4.2 to 3.4.4
- css/settings.css +9 -0
- ecwid-shopping-cart.php +91 -31
- includes/class-ecwid-message-manager.php +4 -0
- includes/class-ecwid-oauth.php +256 -24
- js/recently-viewed.js +0 -1
- languages/ecwid-shopping-cart-it_IT.mo +0 -0
- languages/ecwid-shopping-cart-it_IT.po +89 -32
- languages/ecwid-shopping-cart-ru_RU.mo +0 -0
- languages/ecwid-shopping-cart-ru_RU.po +2 -2
- languages/ecwid-shopping-cart-tr_TR.mo +0 -0
- languages/ecwid-shopping-cart-tr_TR.po +132 -78
- lib/phpseclib/AES.php +197 -0
- lib/phpseclib/Base.php +2593 -0
- lib/phpseclib/LICENSE +21 -0
- lib/phpseclib/Rijndael.php +1037 -0
- readme.txt +9 -1
- templates/connect.php +1 -1
- templates/dashboard.php +1 -1
- templates/reconnect.php +37 -17
css/settings.css
CHANGED
@@ -391,6 +391,11 @@ display: none;
|
|
391 |
margin-bottom: 38px;
|
392 |
}
|
393 |
|
|
|
|
|
|
|
|
|
|
|
394 |
.ecwid-connect .box .connect-button {
|
395 |
margin-top: 8px;
|
396 |
}
|
@@ -405,6 +410,10 @@ display: none;
|
|
405 |
font-size: 13px;
|
406 |
}
|
407 |
|
|
|
|
|
|
|
|
|
408 |
.ecwid-connect .box .create-account-link {
|
409 |
margin-top: 35px;
|
410 |
}
|
391 |
margin-bottom: 38px;
|
392 |
}
|
393 |
|
394 |
+
|
395 |
+
.ecwid-connect.ecwid-reconnect .box .greeting-message {
|
396 |
+
margin-bottom: inherit;
|
397 |
+
}
|
398 |
+
|
399 |
.ecwid-connect .box .connect-button {
|
400 |
margin-top: 8px;
|
401 |
}
|
410 |
font-size: 13px;
|
411 |
}
|
412 |
|
413 |
+
.ecwid-connect .box .note.reconnect-message {
|
414 |
+
margin-bottom: 38px;
|
415 |
+
color: #707070;
|
416 |
+
}
|
417 |
.ecwid-connect .box .create-account-link {
|
418 |
margin-top: 35px;
|
419 |
}
|
ecwid-shopping-cart.php
CHANGED
@@ -5,7 +5,7 @@ Plugin URI: http://www.ecwid.com?source=wporg
|
|
5 |
Description: Ecwid is a free full-featured shopping cart. It can be easily integrated with any Wordpress blog and takes less than 5 minutes to set up.
|
6 |
Text Domain: ecwid-shopping-cart
|
7 |
Author: Ecwid Team
|
8 |
-
Version: 3.4.
|
9 |
Author URI: http://www.ecwid.com?source=wporg
|
10 |
*/
|
11 |
|
@@ -26,7 +26,6 @@ if ( ! defined( 'ECWID_PLUGIN_URL' ) ) {
|
|
26 |
define( 'ECWID_PLUGIN_URL', plugin_dir_url( realpath(__FILE__) ) );
|
27 |
}
|
28 |
|
29 |
-
|
30 |
// Older versions of Google XML Sitemaps plugin generate it in admin, newer in site area, so the hook should be assigned in both of them
|
31 |
add_action('sm_buildmap', 'ecwid_build_google_xml_sitemap');
|
32 |
|
@@ -40,6 +39,7 @@ add_filter('plugins_loaded', 'ecwid_load_textdomain');
|
|
40 |
if ( is_admin() ){
|
41 |
add_action('admin_init', 'ecwid_settings_api_init');
|
42 |
add_action('admin_init', 'ecwid_check_version');
|
|
|
43 |
add_action('admin_notices', 'ecwid_show_admin_messages');
|
44 |
add_action('admin_menu', 'ecwid_options_add_page');
|
45 |
add_action('wp_dashboard_setup', 'ecwid_add_dashboard_widgets' );
|
@@ -69,7 +69,7 @@ if ( is_admin() ){
|
|
69 |
add_action('wp', 'ecwid_seo_ultimate_compatibility', 0);
|
70 |
add_action('wp', 'ecwid_remove_default_canonical');
|
71 |
add_filter('wp', 'ecwid_seo_compatibility_init', 0);
|
72 |
-
add_filter('wp_title', 'ecwid_seo_title',
|
73 |
add_action('plugins_loaded', 'ecwid_minifier_compatibility', 0);
|
74 |
add_action('wp_head', 'ecwid_meta_description', 0);
|
75 |
add_action('wp_head', 'ecwid_ajax_crawling_fragment');
|
@@ -417,6 +417,12 @@ function ecwid_check_version()
|
|
417 |
$current_version = $plugin_data['Version'];
|
418 |
$stored_version = get_option('ecwid_plugin_version', null);
|
419 |
|
|
|
|
|
|
|
|
|
|
|
|
|
420 |
$fresh_install = !$stored_version;
|
421 |
$upgrade = $stored_version && version_compare($current_version, $stored_version) > 0;
|
422 |
|
@@ -441,19 +447,6 @@ function ecwid_check_version()
|
|
441 |
|
442 |
add_option('ecwid_use_new_horizontal_categories', '');
|
443 |
}
|
444 |
-
|
445 |
-
$migration_since_version = get_option('ecwid_plugin_migration_since_version', null);
|
446 |
-
|
447 |
-
if ($migration_since_version == '3.4' || $migration_since_version == '3.4.1' || is_null($migration_since_version)) {
|
448 |
-
|
449 |
-
$install_date = get_option('ecwid_installation_date');
|
450 |
-
if ($install_date < strtotime("18 September 2015")) {
|
451 |
-
update_option('ecwid_plugin_migration_since_version', '0');
|
452 |
-
} elseif (is_null($migration_since_version)) {
|
453 |
-
update_option('ecwid_plugin_migration_since_version', $current_version);
|
454 |
-
}
|
455 |
-
}
|
456 |
-
|
457 |
}
|
458 |
|
459 |
function ecwid_migrations_is_original_plugin_version_older_than($version)
|
@@ -549,10 +542,22 @@ function ecwid_seo_compatibility_init($title)
|
|
549 |
// Title
|
550 |
ecwid_override_option('aiosp_rewrite_titles', false);
|
551 |
|
|
|
552 |
return $title;
|
553 |
|
554 |
}
|
555 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
556 |
function ecwid_seo_compatibility_restore()
|
557 |
{
|
558 |
if (!array_key_exists('_escaped_fragment_', $_GET) || !ecwid_page_has_productbrowser()) {
|
@@ -853,10 +858,10 @@ function ecwid_content_started($content)
|
|
853 |
|
854 |
function ecwid_wrap_shortcode_content($content, $name, $attrs)
|
855 |
{
|
856 |
-
return "<!-- Ecwid shopping cart plugin v 3.4.
|
857 |
. ecwid_get_scriptjs_code(@$attrs['lang'])
|
858 |
. "<div class=\"ecwid-shopping-cart-$name\">$content</div>"
|
859 |
-
. "<!-- /noptimize --><!-- END Ecwid Shopping Cart v 3.4.
|
860 |
}
|
861 |
|
862 |
function ecwid_get_scriptjs_code($force_lang = null) {
|
@@ -1384,6 +1389,7 @@ function ecwid_uninstall() {
|
|
1384 |
delete_option('ecwid_api_check_time');
|
1385 |
delete_option('ecwid_show_vote_message');
|
1386 |
delete_option("ecwid_sso_secret_key");
|
|
|
1387 |
delete_option('ecwid_hide_appearance_menu');
|
1388 |
delete_option("ecwid_advanced_theme_layout");
|
1389 |
|
@@ -1583,21 +1589,62 @@ function ecwid_general_settings_do_page() {
|
|
1583 |
}
|
1584 |
}
|
1585 |
|
|
|
|
|
1586 |
if (get_option('ecwid_store_id') == ECWID_DEMO_STORE_ID && !$no_oauth) {
|
1587 |
-
global $ecwid_oauth;
|
1588 |
|
1589 |
$register = !$connection_error && !isset($_GET['connect']) && !@$_COOKIE['ecwid_create_store_clicked'];
|
1590 |
|
1591 |
require_once(ECWID_PLUGIN_DIR . '/templates/landing.php');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1592 |
} else {
|
|
|
|
|
|
|
1593 |
|
1594 |
-
|
1595 |
-
global $ecwid_oauth;
|
1596 |
|
1597 |
-
|
1598 |
-
|
1599 |
-
|
1600 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1601 |
}
|
1602 |
}
|
1603 |
|
@@ -1609,14 +1656,19 @@ function ecwid_admin_post_connect()
|
|
1609 |
update_option('ecwid_api_check_time', 0);
|
1610 |
update_option('ecwid_last_oauth_fail_time', 1);
|
1611 |
wp_redirect('admin.php?page=ecwid');
|
|
|
1612 |
}
|
1613 |
global $ecwid_oauth;
|
1614 |
|
1615 |
if (ecwid_test_oauth(true)) {
|
|
|
1616 |
wp_redirect($ecwid_oauth->get_auth_dialog_url());
|
1617 |
-
} else {
|
1618 |
wp_redirect('admin.php?page=ecwid&oauth=no');
|
|
|
|
|
1619 |
}
|
|
|
1620 |
}
|
1621 |
|
1622 |
function ecwid_test_oauth($force = false)
|
@@ -2209,7 +2261,7 @@ class EcwidRecentlyViewedWidget extends WP_Widget {
|
|
2209 |
if ( $title )
|
2210 |
echo $before_title . $title . $after_title;
|
2211 |
|
2212 |
-
echo ecwid_get_scriptjs_code();
|
2213 |
|
2214 |
$recently_viewed = false;
|
2215 |
if (isset($_COOKIE['ecwid-shopping-cart-recently-viewed'])) {
|
@@ -2229,6 +2281,7 @@ class EcwidRecentlyViewedWidget extends WP_Widget {
|
|
2229 |
$api = ecwid_new_product_api();
|
2230 |
}
|
2231 |
|
|
|
2232 |
$ids = array();
|
2233 |
if ($recently_viewed && isset($recently_viewed->products)) {
|
2234 |
|
@@ -2244,14 +2297,17 @@ class EcwidRecentlyViewedWidget extends WP_Widget {
|
|
2244 |
$product_https = $api->get_product_https($product->id);
|
2245 |
}
|
2246 |
|
|
|
|
|
2247 |
echo <<<HTML
|
2248 |
-
<a class="product$hide" href="$product->link" alt="$
|
2249 |
<div class="ecwid ecwid-SingleProduct ecwid-Product ecwid-Product-$product->id" data-single-product-link="$product->link" itemscope itemtype="http://schema.org/Product" data-single-product-id="$product->id">
|
2250 |
<div itemprop="image" data-force-image="$product_https[imageUrl]"></div>
|
2251 |
<div class="ecwid-title" itemprop="name"></div>
|
2252 |
<div itemtype="http://schema.org/Offer" itemscope itemprop="offers"><div class="ecwid-productBrowser-price ecwid-price" itemprop="price"></div></div>
|
2253 |
</div>
|
2254 |
-
|
|
|
2255 |
</a>
|
2256 |
HTML;
|
2257 |
}
|
@@ -2398,7 +2454,8 @@ function ecwid_gather_stats()
|
|
2398 |
'recently_viewed_widget',
|
2399 |
'avalanche_used',
|
2400 |
'chameleon_used',
|
2401 |
-
'http_post_fails'
|
|
|
2402 |
);
|
2403 |
|
2404 |
$usage_stats = ecwid_gather_usage_stats();
|
@@ -2436,7 +2493,8 @@ function ecwid_gather_usage_stats()
|
|
2436 |
'recently_viewed_widget',
|
2437 |
'avalanche_used',
|
2438 |
'chameleon_used',
|
2439 |
-
'http_post_fails'
|
|
|
2440 |
);
|
2441 |
|
2442 |
$usage_stats = array();
|
@@ -2460,6 +2518,8 @@ function ecwid_gather_usage_stats()
|
|
2460 |
$usage_stats['avalanche_used'] = (bool) is_plugin_active('ecwid-widgets-avalanche/ecwid_widgets_avalanche.php');
|
2461 |
$usage_stats['chameleon_used'] = (bool)get_option('ecwid_use_chameleon');
|
2462 |
$usage_stats['http_post_fails'] = get_option('ecwid_last_oauth_fail_time') > 0;
|
|
|
|
|
2463 |
|
2464 |
return $usage_stats;
|
2465 |
}
|
5 |
Description: Ecwid is a free full-featured shopping cart. It can be easily integrated with any Wordpress blog and takes less than 5 minutes to set up.
|
6 |
Text Domain: ecwid-shopping-cart
|
7 |
Author: Ecwid Team
|
8 |
+
Version: 3.4.4
|
9 |
Author URI: http://www.ecwid.com?source=wporg
|
10 |
*/
|
11 |
|
26 |
define( 'ECWID_PLUGIN_URL', plugin_dir_url( realpath(__FILE__) ) );
|
27 |
}
|
28 |
|
|
|
29 |
// Older versions of Google XML Sitemaps plugin generate it in admin, newer in site area, so the hook should be assigned in both of them
|
30 |
add_action('sm_buildmap', 'ecwid_build_google_xml_sitemap');
|
31 |
|
39 |
if ( is_admin() ){
|
40 |
add_action('admin_init', 'ecwid_settings_api_init');
|
41 |
add_action('admin_init', 'ecwid_check_version');
|
42 |
+
add_action('admin_init', 'ecwid_process_oauth_params');
|
43 |
add_action('admin_notices', 'ecwid_show_admin_messages');
|
44 |
add_action('admin_menu', 'ecwid_options_add_page');
|
45 |
add_action('wp_dashboard_setup', 'ecwid_add_dashboard_widgets' );
|
69 |
add_action('wp', 'ecwid_seo_ultimate_compatibility', 0);
|
70 |
add_action('wp', 'ecwid_remove_default_canonical');
|
71 |
add_filter('wp', 'ecwid_seo_compatibility_init', 0);
|
72 |
+
add_filter('wp_title', 'ecwid_seo_title', 10000);
|
73 |
add_action('plugins_loaded', 'ecwid_minifier_compatibility', 0);
|
74 |
add_action('wp_head', 'ecwid_meta_description', 0);
|
75 |
add_action('wp_head', 'ecwid_ajax_crawling_fragment');
|
417 |
$current_version = $plugin_data['Version'];
|
418 |
$stored_version = get_option('ecwid_plugin_version', null);
|
419 |
|
420 |
+
|
421 |
+
$migration_since_version = get_option('ecwid_plugin_migration_since_version', null);
|
422 |
+
if (is_null($migration_since_version)) {
|
423 |
+
update_option('ecwid_plugin_migration_since_version', $current_version);
|
424 |
+
}
|
425 |
+
|
426 |
$fresh_install = !$stored_version;
|
427 |
$upgrade = $stored_version && version_compare($current_version, $stored_version) > 0;
|
428 |
|
447 |
|
448 |
add_option('ecwid_use_new_horizontal_categories', '');
|
449 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
450 |
}
|
451 |
|
452 |
function ecwid_migrations_is_original_plugin_version_older_than($version)
|
542 |
// Title
|
543 |
ecwid_override_option('aiosp_rewrite_titles', false);
|
544 |
|
545 |
+
add_action('amt_basic_metadata_head', 'ecwid_amt_remove_description');
|
546 |
return $title;
|
547 |
|
548 |
}
|
549 |
|
550 |
+
function ecwid_amt_remove_description($params)
|
551 |
+
{
|
552 |
+
foreach ($params as $key => $value) {
|
553 |
+
if (preg_match('/meta name="description"/', $value)) {
|
554 |
+
unset ($params[$key]);
|
555 |
+
}
|
556 |
+
}
|
557 |
+
|
558 |
+
return $params;
|
559 |
+
}
|
560 |
+
|
561 |
function ecwid_seo_compatibility_restore()
|
562 |
{
|
563 |
if (!array_key_exists('_escaped_fragment_', $_GET) || !ecwid_page_has_productbrowser()) {
|
858 |
|
859 |
function ecwid_wrap_shortcode_content($content, $name, $attrs)
|
860 |
{
|
861 |
+
return "<!-- Ecwid shopping cart plugin v 3.4.4 --><!-- noptimize -->"
|
862 |
. ecwid_get_scriptjs_code(@$attrs['lang'])
|
863 |
. "<div class=\"ecwid-shopping-cart-$name\">$content</div>"
|
864 |
+
. "<!-- /noptimize --><!-- END Ecwid Shopping Cart v 3.4.4 -->";
|
865 |
}
|
866 |
|
867 |
function ecwid_get_scriptjs_code($force_lang = null) {
|
1389 |
delete_option('ecwid_api_check_time');
|
1390 |
delete_option('ecwid_show_vote_message');
|
1391 |
delete_option("ecwid_sso_secret_key");
|
1392 |
+
delete_option("ecwid_installation_date");
|
1393 |
delete_option('ecwid_hide_appearance_menu');
|
1394 |
delete_option("ecwid_advanced_theme_layout");
|
1395 |
|
1589 |
}
|
1590 |
}
|
1591 |
|
1592 |
+
global $ecwid_oauth;
|
1593 |
+
|
1594 |
if (get_option('ecwid_store_id') == ECWID_DEMO_STORE_ID && !$no_oauth) {
|
|
|
1595 |
|
1596 |
$register = !$connection_error && !isset($_GET['connect']) && !@$_COOKIE['ecwid_create_store_clicked'];
|
1597 |
|
1598 |
require_once(ECWID_PLUGIN_DIR . '/templates/landing.php');
|
1599 |
+
} else if (isset($_GET['reconnect'])) {
|
1600 |
+
if (isset($_GET['reason'])) switch ($_GET['reason']) {
|
1601 |
+
case '1': $reconnect_message = "Message 1"; break;
|
1602 |
+
case '2': $reconnect_message = "Message 2"; break;
|
1603 |
+
}
|
1604 |
+
|
1605 |
+
$scopes = '';
|
1606 |
+
|
1607 |
+
$connection_error = isset($_GET['connection_error']);
|
1608 |
+
|
1609 |
+
require_once ECWID_PLUGIN_DIR . '/templates/reconnect.php';
|
1610 |
+
} else if (get_ecwid_store_id() == ECWID_DEMO_STORE_ID || isset($_GET['connection_error'])) {
|
1611 |
+
|
1612 |
+
require_once ECWID_PLUGIN_DIR . '/templates/connect.php';
|
1613 |
} else {
|
1614 |
+
require_once ECWID_PLUGIN_DIR . '/templates/dashboard.php';
|
1615 |
+
}
|
1616 |
+
}
|
1617 |
|
1618 |
+
function ecwid_process_oauth_params() {
|
|
|
1619 |
|
1620 |
+
if (strtoupper($_SERVER['REQUEST_METHOD']) != 'GET' || !isset($_GET['page'])) {
|
1621 |
+
return;
|
1622 |
+
}
|
1623 |
+
|
1624 |
+
$is_dashboard = $_GET['page'] == 'ecwid';
|
1625 |
+
|
1626 |
+
if (!$is_dashboard) {
|
1627 |
+
return;
|
1628 |
+
}
|
1629 |
+
|
1630 |
+
global $ecwid_oauth;
|
1631 |
+
$is_connect = get_ecwid_store_id() != ECWID_DEMO_STORE_ID && !isset($_GET['connection_error']);
|
1632 |
+
|
1633 |
+
$is_reconnect = isset($_GET['reconnect']) && !isset($_GET['connection_error']);
|
1634 |
+
|
1635 |
+
if ($is_connect) {
|
1636 |
+
$ecwid_oauth->update_state( array( 'mode' => 'connect' ) );
|
1637 |
+
}
|
1638 |
+
|
1639 |
+
if ($is_reconnect) {
|
1640 |
+
$ecwid_oauth->update_state( array(
|
1641 |
+
'mode' => 'reconnect',
|
1642 |
+
// explicitly set to empty array if not available to reset current state
|
1643 |
+
'scope' => isset($_GET['scope']) ? $_GET['scope'] : array(),
|
1644 |
+
// explicitly set to empty string if not available to reset current state
|
1645 |
+
'return_url' => isset($_GET['return-url']) ? $_GET['return-url'] : '',
|
1646 |
+
'reason' => isset($_GET['reason']) ? $_GET['reason'] : ''
|
1647 |
+
));
|
1648 |
}
|
1649 |
}
|
1650 |
|
1656 |
update_option('ecwid_api_check_time', 0);
|
1657 |
update_option('ecwid_last_oauth_fail_time', 1);
|
1658 |
wp_redirect('admin.php?page=ecwid');
|
1659 |
+
exit;
|
1660 |
}
|
1661 |
global $ecwid_oauth;
|
1662 |
|
1663 |
if (ecwid_test_oauth(true)) {
|
1664 |
+
|
1665 |
wp_redirect($ecwid_oauth->get_auth_dialog_url());
|
1666 |
+
} else if (!isset($_GET['reconnect'])) {
|
1667 |
wp_redirect('admin.php?page=ecwid&oauth=no');
|
1668 |
+
} else {
|
1669 |
+
wp_redirect('admin.php?page=ecwid&reconnect&connection_error');
|
1670 |
}
|
1671 |
+
exit;
|
1672 |
}
|
1673 |
|
1674 |
function ecwid_test_oauth($force = false)
|
2261 |
if ( $title )
|
2262 |
echo $before_title . $title . $after_title;
|
2263 |
|
2264 |
+
echo '<!-- noptimize -->' . ecwid_get_scriptjs_code() . '<!-- /noptimize -->';
|
2265 |
|
2266 |
$recently_viewed = false;
|
2267 |
if (isset($_COOKIE['ecwid-shopping-cart-recently-viewed'])) {
|
2281 |
$api = ecwid_new_product_api();
|
2282 |
}
|
2283 |
|
2284 |
+
$counter = 0;
|
2285 |
$ids = array();
|
2286 |
if ($recently_viewed && isset($recently_viewed->products)) {
|
2287 |
|
2297 |
$product_https = $api->get_product_https($product->id);
|
2298 |
}
|
2299 |
|
2300 |
+
$name = isset($product_https) ? $product_https['name']: '';
|
2301 |
+
|
2302 |
echo <<<HTML
|
2303 |
+
<a class="product$hide" href="$product->link" alt="$name" title="$name">
|
2304 |
<div class="ecwid ecwid-SingleProduct ecwid-Product ecwid-Product-$product->id" data-single-product-link="$product->link" itemscope itemtype="http://schema.org/Product" data-single-product-id="$product->id">
|
2305 |
<div itemprop="image" data-force-image="$product_https[imageUrl]"></div>
|
2306 |
<div class="ecwid-title" itemprop="name"></div>
|
2307 |
<div itemtype="http://schema.org/Offer" itemscope itemprop="offers"><div class="ecwid-productBrowser-price ecwid-price" itemprop="price"></div></div>
|
2308 |
</div>
|
2309 |
+
|
2310 |
+
<!-- noptimize --><script type="text/javascript">xSingleProduct();</script><!-- /noptimize -->
|
2311 |
</a>
|
2312 |
HTML;
|
2313 |
}
|
2454 |
'recently_viewed_widget',
|
2455 |
'avalanche_used',
|
2456 |
'chameleon_used',
|
2457 |
+
'http_post_fails',
|
2458 |
+
'ecwid_use_new_horizontal_categories'
|
2459 |
);
|
2460 |
|
2461 |
$usage_stats = ecwid_gather_usage_stats();
|
2493 |
'recently_viewed_widget',
|
2494 |
'avalanche_used',
|
2495 |
'chameleon_used',
|
2496 |
+
'http_post_fails',
|
2497 |
+
'ecwid_use_new_horizontal_categories'
|
2498 |
);
|
2499 |
|
2500 |
$usage_stats = array();
|
2518 |
$usage_stats['avalanche_used'] = (bool) is_plugin_active('ecwid-widgets-avalanche/ecwid_widgets_avalanche.php');
|
2519 |
$usage_stats['chameleon_used'] = (bool)get_option('ecwid_use_chameleon');
|
2520 |
$usage_stats['http_post_fails'] = get_option('ecwid_last_oauth_fail_time') > 0;
|
2521 |
+
$usage_stats['ecwid_use_new_horizontal_categories'] = (bool) get_option('ecwid_use_new_horizontal_categories');
|
2522 |
+
|
2523 |
|
2524 |
return $usage_stats;
|
2525 |
}
|
includes/class-ecwid-message-manager.php
CHANGED
@@ -212,6 +212,10 @@ class Ecwid_Message_Manager
|
|
212 |
$admin_page = $screen->base;
|
213 |
}
|
214 |
|
|
|
|
|
|
|
|
|
215 |
switch ($name) {
|
216 |
case 'on_activate':
|
217 |
return $admin_page == 'plugins' && get_ecwid_store_id() == ECWID_DEMO_STORE_ID;
|
212 |
$admin_page = $screen->base;
|
213 |
}
|
214 |
|
215 |
+
if ($admin_page == 'toplevel_page_ecwid' && isset($_GET['reconnect'])) {
|
216 |
+
return false;
|
217 |
+
}
|
218 |
+
|
219 |
switch ($name) {
|
220 |
case 'on_activate':
|
221 |
return $admin_page == 'plugins' && get_ecwid_store_id() == ECWID_DEMO_STORE_ID;
|
includes/class-ecwid-oauth.php
CHANGED
@@ -1,12 +1,33 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
3 |
class Ecwid_OAuth {
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
public function __construct()
|
6 |
{
|
7 |
add_action('admin_post_ecwid_oauth', array($this, 'process_authorization'));
|
|
|
8 |
add_action('admin_post_ecwid_disconnect', array($this, 'disconnect_store'));
|
9 |
add_action('admin_post_ecwid_show_reconnect', array($this, 'show_reconnect'));
|
|
|
|
|
|
|
|
|
|
|
10 |
}
|
11 |
|
12 |
public function show_reconnect()
|
@@ -22,33 +43,64 @@ class Ecwid_OAuth {
|
|
22 |
return is_array($return);
|
23 |
}
|
24 |
|
25 |
-
public function get_auth_dialog_url(
|
26 |
{
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
return false;
|
29 |
}
|
30 |
|
31 |
$url = 'https://my.ecwid.com/api/oauth/authorize';
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
$
|
36 |
-
$
|
37 |
-
$
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
-
return $url . '?' . build_query( $
|
40 |
}
|
41 |
|
42 |
public function process_authorization()
|
43 |
{
|
|
|
|
|
44 |
if ( isset( $_REQUEST['error'] ) || !isset( $_REQUEST['code'] ) ) {
|
45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
}
|
47 |
|
|
|
|
|
48 |
$params['code'] = $_REQUEST['code'];
|
49 |
-
$params['client_id'] =
|
50 |
-
$params['client_secret'] =
|
51 |
-
$params['redirect_uri'] = admin_url(
|
|
|
52 |
$params['grant_type'] = 'authorization_code';
|
53 |
|
54 |
$return = wp_remote_post('https://my.ecwid.com/api/oauth/token', array('body' => $params));
|
@@ -65,28 +117,57 @@ class Ecwid_OAuth {
|
|
65 |
|| ( $result->token_type != 'Bearer' )
|
66 |
) {
|
67 |
ecwid_log_error(var_export($return, true));
|
68 |
-
return $this->trigger_auth_error();
|
69 |
}
|
70 |
|
71 |
update_option( 'ecwid_store_id', $result->store_id );
|
72 |
-
|
|
|
73 |
|
|
|
|
|
74 |
setcookie('ecwid_create_store_clicked', null, strtotime('-1 day'), ADMIN_COOKIE_PATH, COOKIE_DOMAIN);
|
75 |
|
76 |
-
|
|
|
|
|
|
|
|
|
|
|
77 |
}
|
78 |
|
79 |
public function disconnect_store()
|
80 |
{
|
81 |
update_option( 'ecwid_store_id', '' );
|
82 |
update_option( 'ecwid_oauth_token', '' );
|
83 |
-
update_option('ecwid_is_api_enabled', 'off');
|
84 |
-
update_option('ecwid_api_check_time', 0);
|
85 |
|
86 |
wp_redirect('admin.php?page=ecwid');
|
|
|
87 |
}
|
88 |
|
89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
{
|
91 |
update_option('ecwid_last_oauth_fail_time', time());
|
92 |
|
@@ -96,21 +177,172 @@ class Ecwid_OAuth {
|
|
96 |
$logs = json_decode($logs);
|
97 |
}
|
98 |
|
99 |
-
if (count($logs) > 0) {
|
100 |
$entry = $logs[count($logs) - 1];
|
101 |
if (isset($entry->message)) {
|
102 |
$last_error = $entry->message;
|
103 |
}
|
104 |
}
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
}
|
108 |
|
109 |
-
|
|
|
110 |
|
111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
113 |
-
|
|
|
114 |
}
|
115 |
}
|
116 |
|
1 |
<?php
|
2 |
|
3 |
+
|
4 |
+
include ECWID_PLUGIN_DIR . "lib/phpseclib/AES.php";
|
5 |
+
|
6 |
class Ecwid_OAuth {
|
7 |
|
8 |
+
const OAUTH_CLIENT_ID = 'RD4o2KQimiGUrFZc';
|
9 |
+
const OAUTH_CLIENT_SECRET = 'jEPVdcA3KbzKVrG8FZDgNnsY3wKHDTF8';
|
10 |
+
|
11 |
+
const TOKEN_OPTION_NAME = 'ecwid_oauth_token';
|
12 |
+
|
13 |
+
const MODE_CONNECT = 'connect';
|
14 |
+
const MODE_RECONNECT = 'reconnect';
|
15 |
+
|
16 |
+
protected $crypt = null;
|
17 |
+
|
18 |
+
protected $state;
|
19 |
+
|
20 |
public function __construct()
|
21 |
{
|
22 |
add_action('admin_post_ecwid_oauth', array($this, 'process_authorization'));
|
23 |
+
add_action('admin_post_ecwid_oauth_reconnect', array($this, 'process_authorization'));
|
24 |
add_action('admin_post_ecwid_disconnect', array($this, 'disconnect_store'));
|
25 |
add_action('admin_post_ecwid_show_reconnect', array($this, 'show_reconnect'));
|
26 |
+
|
27 |
+
$this->crypt = new Crypt_AES();
|
28 |
+
$this->_init_crypt();
|
29 |
+
|
30 |
+
$this->_load_state();
|
31 |
}
|
32 |
|
33 |
public function show_reconnect()
|
43 |
return is_array($return);
|
44 |
}
|
45 |
|
46 |
+
public function get_auth_dialog_url()
|
47 |
{
|
48 |
+
$action = 'ecwid_oauth';
|
49 |
+
if ( $this->_is_reconnect() ) {
|
50 |
+
$action = 'ecwid_oauth_reconnect';
|
51 |
+
}
|
52 |
+
|
53 |
+
$redirect_uri = 'admin-post.php?action=' . $action;
|
54 |
+
|
55 |
+
$params = array(
|
56 |
+
'scopes' => implode(' ', $this->_get_scope()),
|
57 |
+
'redirect_uri' => admin_url( $redirect_uri )
|
58 |
+
);
|
59 |
+
|
60 |
+
if ( !is_array( $params )
|
61 |
+
|| empty( $params['scopes'] )
|
62 |
+
) {
|
63 |
return false;
|
64 |
}
|
65 |
|
66 |
$url = 'https://my.ecwid.com/api/oauth/authorize';
|
67 |
|
68 |
+
$query = array();
|
69 |
+
|
70 |
+
$query['source'] = 'wporg';
|
71 |
+
$query['client_id'] = self::OAUTH_CLIENT_ID;
|
72 |
+
$query['redirect_uri'] = $params['redirect_uri'];
|
73 |
+
$query['response_type'] = 'code';
|
74 |
+
$query['scope'] = $params['scopes'];
|
75 |
+
foreach ($query as $key => $value) {
|
76 |
+
$query[$key] = urlencode($value);
|
77 |
+
}
|
78 |
|
79 |
+
return $url . '?' . build_query( $query );
|
80 |
}
|
81 |
|
82 |
public function process_authorization()
|
83 |
{
|
84 |
+
$reconnect = $_REQUEST['action'] == 'ecwid_oauth_reconnect';
|
85 |
+
|
86 |
if ( isset( $_REQUEST['error'] ) || !isset( $_REQUEST['code'] ) ) {
|
87 |
+
if ($reconnect) {
|
88 |
+
$this->update_state(array('mode' => self::MODE_RECONNECT, 'error' => 'cancelled'));
|
89 |
+
} else {
|
90 |
+
$this->update_state(array('mode' => self::MODE_CONNECT, 'error' => 'cancelled'));
|
91 |
+
}
|
92 |
+
|
93 |
+
wp_redirect('admin.php?page=ecwid&connection_error' . ($reconnect ? '&reconnect' : ''));
|
94 |
+
exit;
|
95 |
}
|
96 |
|
97 |
+
$base_admin_url = 'admin-post.php?action=ecwid_oauth' . ($reconnect ? '_reconnect' : '');
|
98 |
+
|
99 |
$params['code'] = $_REQUEST['code'];
|
100 |
+
$params['client_id'] = self::OAUTH_CLIENT_ID;
|
101 |
+
$params['client_secret'] = self::OAUTH_CLIENT_SECRET;
|
102 |
+
$params['redirect_uri'] = admin_url( $base_admin_url );
|
103 |
+
|
104 |
$params['grant_type'] = 'authorization_code';
|
105 |
|
106 |
$return = wp_remote_post('https://my.ecwid.com/api/oauth/token', array('body' => $params));
|
117 |
|| ( $result->token_type != 'Bearer' )
|
118 |
) {
|
119 |
ecwid_log_error(var_export($return, true));
|
120 |
+
return $this->trigger_auth_error($reconnect ? 'reconnect' : 'default');
|
121 |
}
|
122 |
|
123 |
update_option( 'ecwid_store_id', $result->store_id );
|
124 |
+
$this->_init_crypt();
|
125 |
+
$this->_save_token($result->access_token);
|
126 |
|
127 |
+
// Reset "Create store cookie" set previously to display the landing page
|
128 |
+
//in "Connect" mode rather than "Create" mode
|
129 |
setcookie('ecwid_create_store_clicked', null, strtotime('-1 day'), ADMIN_COOKIE_PATH, COOKIE_DOMAIN);
|
130 |
|
131 |
+
if ( isset( $this->state->return_url ) && !empty( $this->state->return_url ) ) {
|
132 |
+
wp_redirect( admin_url( $this->state->return_url ) );
|
133 |
+
} else {
|
134 |
+
wp_redirect( 'admin.php?page=ecwid&settings-updated=true' );
|
135 |
+
}
|
136 |
+
exit;
|
137 |
}
|
138 |
|
139 |
public function disconnect_store()
|
140 |
{
|
141 |
update_option( 'ecwid_store_id', '' );
|
142 |
update_option( 'ecwid_oauth_token', '' );
|
143 |
+
update_option( 'ecwid_is_api_enabled', 'off' );
|
144 |
+
update_option( 'ecwid_api_check_time', 0 );
|
145 |
|
146 |
wp_redirect('admin.php?page=ecwid');
|
147 |
+
exit;
|
148 |
}
|
149 |
|
150 |
+
public function get_safe_scopes_array($scopes)
|
151 |
+
{
|
152 |
+
if (!isset($scopes) || empty($scopes)) {
|
153 |
+
return array( 'read_store_profile', 'read_catalog' );
|
154 |
+
}
|
155 |
+
|
156 |
+
if (!empty($scopes)) {
|
157 |
+
$scopes_array = explode(' ', $scopes);
|
158 |
+
|
159 |
+
foreach ($scopes_array as $key => $scope) {
|
160 |
+
if (!preg_match('/^[a-z_]+$/', $scope)) {
|
161 |
+
unset($scopes_array[$key]);
|
162 |
+
}
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
return $scopes_array;
|
167 |
+
}
|
168 |
+
|
169 |
+
|
170 |
+
protected function trigger_auth_error($mode = 'default')
|
171 |
{
|
172 |
update_option('ecwid_last_oauth_fail_time', time());
|
173 |
|
177 |
$logs = json_decode($logs);
|
178 |
}
|
179 |
|
180 |
+
if (is_array($logs) && count($logs) > 0) {
|
181 |
$entry = $logs[count($logs) - 1];
|
182 |
if (isset($entry->message)) {
|
183 |
$last_error = $entry->message;
|
184 |
}
|
185 |
}
|
186 |
+
|
187 |
+
if ( $mode == self::MODE_RECONNECT ) {
|
188 |
+
$this->update_state(array(
|
189 |
+
'mode' => 'reconnect',
|
190 |
+
'error' => 'other'
|
191 |
+
));
|
192 |
+
}
|
193 |
+
|
194 |
+
if (isset($last_error)) {
|
195 |
+
$url = 'http://' . APP_ECWID_COM . '/script.js?805056&data_platform=wporg&data_wporg_error=' . urlencode($last_error) . '&url=' . urlencode(get_bloginfo('url'));
|
196 |
+
wp_remote_get($url);
|
197 |
+
}
|
198 |
+
|
199 |
+
wp_redirect('admin.php?page=ecwid&connection_error' . ($mode == self::MODE_RECONNECT ? '&reconnect' : ''));
|
200 |
+
exit;
|
201 |
+
}
|
202 |
+
|
203 |
+
public function get_oauth_token()
|
204 |
+
{
|
205 |
+
if ($this->is_initialized()) {
|
206 |
+
return $this->_load_token();
|
207 |
}
|
208 |
|
209 |
+
return null;
|
210 |
+
}
|
211 |
|
212 |
+
protected function _get_scope() {
|
213 |
+
$default = array( 'read_store_profile', 'read_catalog' );
|
214 |
+
|
215 |
+
$scopes = array();
|
216 |
+
if ( $this->_is_reconnect() ) {
|
217 |
+
$scopes = isset($this->state->reconnect_scopes) && is_array($this->state->reconnect_scopes)
|
218 |
+
? $this->state->reconnect_scopes
|
219 |
+
: array();
|
220 |
+
}
|
221 |
+
|
222 |
+
$scopes = array_merge($scopes, $default);
|
223 |
+
|
224 |
+
return $scopes;
|
225 |
+
}
|
226 |
+
|
227 |
+
public function is_initialized()
|
228 |
+
{
|
229 |
+
return get_option( self::TOKEN_OPTION_NAME );
|
230 |
+
}
|
231 |
+
|
232 |
+
protected function _save_token($token)
|
233 |
+
{
|
234 |
+
$value = base64_encode($this->crypt->encrypt($token));
|
235 |
+
|
236 |
+
update_option(self::TOKEN_OPTION_NAME, $value);
|
237 |
+
}
|
238 |
+
|
239 |
+
protected function _load_token()
|
240 |
+
{
|
241 |
+
|
242 |
+
$db_value = get_option(self::TOKEN_OPTION_NAME);
|
243 |
+
if (empty($db_value)) return false;
|
244 |
+
|
245 |
+
if (strlen($db_value) == 64) {
|
246 |
+
$encrypted = base64_decode($db_value);
|
247 |
+
if (empty($encrypted)) return false;
|
248 |
+
|
249 |
+
$token = $this->crypt->decrypt($encrypted);
|
250 |
+
} else {
|
251 |
+
$token = $db_value;
|
252 |
+
}
|
253 |
+
|
254 |
+
return $token;
|
255 |
+
}
|
256 |
+
|
257 |
+
public function _init_crypt() {
|
258 |
+
$this->crypt->setIV( substr( md5( SECURE_AUTH_SALT . get_option('ecwid_store_id') ), 0, 16 ) );
|
259 |
+
$this->crypt->setKey( SECURE_AUTH_KEY );
|
260 |
+
}
|
261 |
+
|
262 |
+
protected function _load_state() {
|
263 |
+
if (isset($_COOKIE['ecwid_oauth_state'])) {
|
264 |
+
$this->state = unserialize( $_COOKIE['ecwid_oauth_state'] );
|
265 |
+
} else {
|
266 |
+
$this->state = new stdClass();
|
267 |
+
$this->state->reconnect_scopes = array();
|
268 |
+
$this->state->reconnect_error = '';
|
269 |
+
$this->state->return_url = '';
|
270 |
+
$this->state->reason = '';
|
271 |
+
}
|
272 |
+
|
273 |
+
$this->state->create_store_clicked = @$_COOKIE['ecwid_create_store_clicked'];
|
274 |
+
}
|
275 |
+
|
276 |
+
public function get_state() {
|
277 |
+
return $this->state;
|
278 |
+
}
|
279 |
+
|
280 |
+
public function was_create_store_clicked() {
|
281 |
+
return $this->state->create_store_clicked;
|
282 |
+
}
|
283 |
+
|
284 |
+
protected function _save_state() {
|
285 |
+
setcookie('ecwid_oauth_state', serialize($this->state), strtotime('+1 day'), ADMIN_COOKIE_PATH, COOKIE_DOMAIN);
|
286 |
+
}
|
287 |
+
|
288 |
+
public function get_reconnect_error() {
|
289 |
+
return $this->state->reconnect_error;
|
290 |
+
}
|
291 |
+
|
292 |
+
public function update_state($params) {
|
293 |
+
|
294 |
+
if (isset($params['mode'])) {
|
295 |
+
$this->state->mode = $params['mode'] == self::MODE_RECONNECT ? self::MODE_RECONNECT : self::MODE_CONNECT;
|
296 |
+
}
|
297 |
+
|
298 |
+
if ( $this->_is_reconnect() ) {
|
299 |
+
if ( isset( $params['scope'] ) ) {
|
300 |
+
$this->state->reconnect_scopes = $this->get_safe_scopes_array( @$params['scope'] );
|
301 |
+
}
|
302 |
+
if ( isset( $params['return_url'] ) ) {
|
303 |
+
$this->state->return_url = $params['return_url'];
|
304 |
+
}
|
305 |
+
|
306 |
+
if ( isset( $params['error'] ) ) {
|
307 |
+
$this->state->reconnect_error = $params['error'];
|
308 |
+
}
|
309 |
+
|
310 |
+
if ( isset( $params['reason'] ) ) {
|
311 |
+
$this->state->reason = $params['reason'];
|
312 |
+
}
|
313 |
+
}
|
314 |
+
|
315 |
+
$this->_save_state();
|
316 |
+
}
|
317 |
+
|
318 |
+
public function get_error() {
|
319 |
+
|
320 |
+
if ($this->_is_reconnect()) {
|
321 |
+
return $this->state->reconnect_error;
|
322 |
+
} else {
|
323 |
+
return $this->state->error;
|
324 |
+
}
|
325 |
+
}
|
326 |
+
|
327 |
+
public function get_reconnect_message() {
|
328 |
+
$reconnect_message = '';
|
329 |
+
|
330 |
+
if (isset($this->state->reason)) {
|
331 |
+
switch ( $this->state->reason ) {
|
332 |
+
case '1':
|
333 |
+
$reconnect_message = "Message 1";
|
334 |
+
break;
|
335 |
+
case '2':
|
336 |
+
$reconnect_message = "Message 2";
|
337 |
+
break;
|
338 |
+
}
|
339 |
+
}
|
340 |
+
|
341 |
+
return $reconnect_message;
|
342 |
+
}
|
343 |
|
344 |
+
protected function _is_reconnect() {
|
345 |
+
return $this->state->mode == self::MODE_RECONNECT;
|
346 |
}
|
347 |
}
|
348 |
|
js/recently-viewed.js
CHANGED
@@ -79,4 +79,3 @@ jQuery.widget('ecwid.recentlyViewedProducts', jQuery.ecwid.productsList, {
|
|
79 |
}
|
80 |
});
|
81 |
|
82 |
-
jQuery('.ecwid-recently-viewed-products').recentlyViewedProducts();
|
79 |
}
|
80 |
});
|
81 |
|
|
languages/ecwid-shopping-cart-it_IT.mo
CHANGED
Binary file
|
languages/ecwid-shopping-cart-it_IT.po
CHANGED
@@ -58,8 +58,11 @@ msgstr "Avanzate"
|
|
58 |
msgid "Hidden category"
|
59 |
msgstr "Categoria nascosta"
|
60 |
|
61 |
-
msgid "
|
62 |
-
msgstr "
|
|
|
|
|
|
|
63 |
|
64 |
msgid "Ecwid Badge"
|
65 |
msgstr "Ecwid Badge"
|
@@ -79,42 +82,51 @@ msgstr "Ecwid shopping cart"
|
|
79 |
msgid "Ecwid e-commerce widgets"
|
80 |
msgstr "Widget Ecwid e-commerce "
|
81 |
|
82 |
-
msgid "
|
83 |
-
msgstr "
|
|
|
|
|
|
|
84 |
|
85 |
-
msgid "
|
86 |
-
msgstr "
|
87 |
|
88 |
-
msgid "
|
89 |
-
msgstr "
|
90 |
|
91 |
-
msgid "
|
92 |
-
msgstr "
|
93 |
|
94 |
-
msgid "
|
95 |
-
msgstr "
|
96 |
|
97 |
-
msgid "
|
98 |
-
msgstr "
|
99 |
|
100 |
-
msgid "
|
101 |
-
msgstr "
|
102 |
|
103 |
-
msgid "
|
104 |
-
msgstr "
|
105 |
|
106 |
-
msgid "
|
107 |
-
msgstr "
|
108 |
|
109 |
msgid "Shop"
|
110 |
msgstr "Negozio"
|
111 |
|
112 |
-
msgid "
|
113 |
-
msgstr "
|
114 |
|
115 |
msgid "Recently Viewed Products"
|
116 |
msgstr "Prodotti visti recentemente"
|
117 |
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
msgid "Number of products to show"
|
119 |
msgstr "Numero di prodotti da mostrare"
|
120 |
|
@@ -202,6 +214,21 @@ msgstr "Questa funzione opzionale consente di abilitare la Sign-on Secret Key, q
|
|
202 |
msgid "In order to enable this feature, opt to use a secret key. You will find this key in your Ecwid control panel, at \"System Settings > Apps > Legacy API Keys > Single Sign-On Secret Key\" page. This feature is available for <a href=\"http://www.ecwid.com/compare-plans.html\" target=\"_blank\">paid users</a> only."
|
203 |
msgstr "Per abilitare questa funzione è necessario essere in possesso di una chiave segreta. Troverai questo pulsante nel pannello di controllo Ecwid, in \"Impostazioni di sistema > Apps > Single Sign-on API secret key\" . Questa funzione è disponibile per tutti gli <a href=\"http://www.ecwid.com/compare-plans.html\" target=\"_blank\">utenti paganti</a>."
|
204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
msgid "Save changes"
|
206 |
msgstr "Salva modifiche"
|
207 |
|
@@ -214,14 +241,14 @@ msgstr "Mostra casella di ricerca sopra prodotti"
|
|
214 |
msgid "Or you can add search box to your website's toolbar using <a href=\"%s\">WordPress native widgets</a>"
|
215 |
msgstr "Puoi anche aggiungere alla barra degli strumenti la casella di ricerca del tuo sito web utilizzando i <a href=\"%s\">widgets nativi di WordPress</a>"
|
216 |
|
217 |
-
msgid "Display
|
218 |
-
msgstr "
|
219 |
|
220 |
msgid "Or you can add vertical categories to your website's toolbar using <a href=\"%s\">WordPress native widgets</a>"
|
221 |
msgstr "Puoi anche aggiungere alla barra degli strumenti le categorie verticali utilizzando i <a href=\"%s\">widgets nativi di WordPress</a>"
|
222 |
|
223 |
-
msgid "Enable minicart attached to
|
224 |
-
msgstr "
|
225 |
|
226 |
msgid "You should disable this option, if you added minicart to your website's sidebar"
|
227 |
msgstr "È necessario disattivare questa opzione, se hai aggiunto il carrello al tuo sito web sidebar"
|
@@ -262,15 +289,27 @@ msgstr "Modalità di visualizzazione predefinita nei risultati di ricerca"
|
|
262 |
msgid "Connect your store<br /> to this WordPress site"
|
263 |
msgstr "Collega il tuo negozio<br /> a questo sito WordPress"
|
264 |
|
|
|
|
|
|
|
265 |
msgid "Connect Ecwid store"
|
266 |
msgstr "Collega Ecwid store"
|
267 |
|
|
|
|
|
|
|
268 |
msgid "After clicking button you need to login and accept permissions to use our plugin"
|
269 |
msgstr "Dopo aver cliccato il pulsante devi accedere e accettare le autorizzazioni necessarie per utilizzare il nostro plugin"
|
270 |
|
271 |
msgid "Connection error - after clicking button you need to login and accept permissions to use our plugin. Please, try again."
|
272 |
msgstr "Errore di connessione - dopo aver cliccato il pulsante, è necessario accedere e accettare le autorizzazioni necessarie per utilizzare il nostro plugin. Per favore, riprova."
|
273 |
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
msgid "Don't have Ecwid account? Create it here"
|
275 |
msgstr "Non hai un accont Ecwid? Crealo qui"
|
276 |
|
@@ -382,8 +421,8 @@ msgstr "Ecwid i comatibile con il tuo<br>“%s” tema WordPress<br>e altri temi
|
|
382 |
msgid "Free and always up to date"
|
383 |
msgstr "Gratuito e sempre aggiornato"
|
384 |
|
385 |
-
msgid "Free plan always available with tons of features<br>at no additional cost.
|
386 |
-
msgstr "
|
387 |
|
388 |
msgid "Responsive design"
|
389 |
msgstr "Design eccezionale"
|
@@ -400,8 +439,8 @@ msgstr "Checkout sicuro con oltre 40<br />opzioni di pagamento"
|
|
400 |
msgid "Global Reach"
|
401 |
msgstr "Portata globale"
|
402 |
|
403 |
-
msgid "More than
|
404 |
-
msgstr "
|
405 |
|
406 |
msgid "Start selling <br>on your WordPress <nobr>site for free</nobr>"
|
407 |
msgstr "Inizia a vendere <br>sul tuo WordPress <nobr>sito gratis</nobr>"
|
@@ -439,8 +478,8 @@ msgstr "Mostra ricerca"
|
|
439 |
msgid "Show minicart"
|
440 |
msgstr "Mostra carrello"
|
441 |
|
442 |
-
msgid "Show
|
443 |
-
msgstr "
|
444 |
|
445 |
msgid "Additionally, you can add store controls to your website's toolbar using <a %s>WordPress native widgets</a>"
|
446 |
msgstr "Inoltre, è possibile aggiungere altri controlli alla barra degli strumenti del tuo sito Web utilizzando i <a %s>widgets nativi WordPress</a>"
|
@@ -457,3 +496,21 @@ msgstr "Qui verrà mostrato il tuo negozio!"
|
|
457 |
msgid "Demo Store"
|
458 |
msgstr "Negozio demo"
|
459 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
msgid "Hidden category"
|
59 |
msgstr "Categoria nascosta"
|
60 |
|
61 |
+
msgid "Recommendations for Your Online Store"
|
62 |
+
msgstr "Consigli per il tuo negozio Online"
|
63 |
+
|
64 |
+
msgid "Do you like Ecwid and want to help it grow? You can add this fancy 'Powered by Ecwid' badge on your site to show your visitors that you're a proud user of Ecwid."
|
65 |
+
msgstr "Do you like Ecwid and want to help it grow? You can add this fancy 'Powered by Ecwid' badge on your site to show your visitors that you're a proud user of Ecwid."
|
66 |
|
67 |
msgid "Ecwid Badge"
|
68 |
msgstr "Ecwid Badge"
|
82 |
msgid "Ecwid e-commerce widgets"
|
83 |
msgstr "Widget Ecwid e-commerce "
|
84 |
|
85 |
+
msgid "Adds a cart widget for customer to see the products they added to the cart."
|
86 |
+
msgstr "Adds a cart widget for customer to see the products they added to the cart."
|
87 |
+
|
88 |
+
msgid "Shopping Cart"
|
89 |
+
msgstr "Shopping Cart"
|
90 |
|
91 |
+
msgid "Adds a compact cart widget for customer to see the products they added to the cart."
|
92 |
+
msgstr "Adds a compact cart widget for customer to see the products they added to the cart."
|
93 |
|
94 |
+
msgid "Shopping Cart (Mini)"
|
95 |
+
msgstr "Shopping Cart (Mini)"
|
96 |
|
97 |
+
msgid "Displays a simple search box for your customers to find a product in your storex"
|
98 |
+
msgstr "Displays a simple search box for your customers to find a product in your storex"
|
99 |
|
100 |
+
msgid "Product Search"
|
101 |
+
msgstr "Product Search"
|
102 |
|
103 |
+
msgid "Adds vertical categories block to let the customer navigate your store."
|
104 |
+
msgstr "Adds vertical categories block to let the customer navigate your store."
|
105 |
|
106 |
+
msgid "Store Categories"
|
107 |
+
msgstr "Store Categories"
|
108 |
|
109 |
+
msgid "Displays a link to the store page in sidebar for customer to quickly access your store from any page on the site."
|
110 |
+
msgstr "Displays a link to the store page in sidebar for customer to quickly access your store from any page on the site."
|
111 |
|
112 |
+
msgid "Store Page Link"
|
113 |
+
msgstr "Store Page Link"
|
114 |
|
115 |
msgid "Shop"
|
116 |
msgstr "Negozio"
|
117 |
|
118 |
+
msgid "Displays a list of products recently viewed by the customer to easily return to the products they saw in your shop."
|
119 |
+
msgstr "Displays a list of products recently viewed by the customer to easily return to the products they saw in your shop."
|
120 |
|
121 |
msgid "Recently Viewed Products"
|
122 |
msgstr "Prodotti visti recentemente"
|
123 |
|
124 |
+
msgid "You have not viewed any product yet. Open store."
|
125 |
+
msgstr "You have not viewed any product yet. Open store."
|
126 |
+
|
127 |
+
msgid "Store Link Title"
|
128 |
+
msgstr "Titolo link per il negozio"
|
129 |
+
|
130 |
msgid "Number of products to show"
|
131 |
msgstr "Numero di prodotti da mostrare"
|
132 |
|
214 |
msgid "In order to enable this feature, opt to use a secret key. You will find this key in your Ecwid control panel, at \"System Settings > Apps > Legacy API Keys > Single Sign-On Secret Key\" page. This feature is available for <a href=\"http://www.ecwid.com/compare-plans.html\" target=\"_blank\">paid users</a> only."
|
215 |
msgstr "Per abilitare questa funzione è necessario essere in possesso di una chiave segreta. Troverai questo pulsante nel pannello di controllo Ecwid, in \"Impostazioni di sistema > Apps > Single Sign-on API secret key\" . Questa funzione è disponibile per tutti gli <a href=\"http://www.ecwid.com/compare-plans.html\" target=\"_blank\">utenti paganti</a>."
|
216 |
|
217 |
+
msgid "Chameleon skin <sup>beta</sup>"
|
218 |
+
msgstr "Tema Chameleon <sup>beta</sup>"
|
219 |
+
|
220 |
+
msgid "Automatic adjustment of your store design to your Wordpress theme. Whatever Wordpress theme you use, Ecwid will detect predominant colors and font and use them in your product catalog."
|
221 |
+
msgstr "Regolazione automatica del design del tuo negozio per il tema Wordpress. Qualsiasi tema Wordpress utilizzi, Ecwid rileverà font e colori predominanti e li utilizzerà nel tuo catalogo prodotti."
|
222 |
+
|
223 |
+
msgid "Please note this functionality is in beta. So if you run into difficulties or find problems with Chameleon, please <a %s>let us know</a>."
|
224 |
+
msgstr "Please note this functionality is in beta. So if you run into difficulties or find problems with Chameleon, please <a %s>let us know</a>."
|
225 |
+
|
226 |
+
msgid "Enable the new category menu"
|
227 |
+
msgstr "Enable the new category menu"
|
228 |
+
|
229 |
+
msgid "The new category menu looks better and is more mobile-friendly. If you haven't yet added category menu to your store page, you can do that in the <a %s>store page editor</a> (enable the \"Show categories\" option)"
|
230 |
+
msgstr "The new category menu looks better and is more mobile-friendly. If you haven't yet added category menu to your store page, you can do that in the <a %s>store page editor</a> (enable the \"Show categories\" option)"
|
231 |
+
|
232 |
msgid "Save changes"
|
233 |
msgstr "Salva modifiche"
|
234 |
|
241 |
msgid "Or you can add search box to your website's toolbar using <a href=\"%s\">WordPress native widgets</a>"
|
242 |
msgstr "Puoi anche aggiungere alla barra degli strumenti la casella di ricerca del tuo sito web utilizzando i <a href=\"%s\">widgets nativi di WordPress</a>"
|
243 |
|
244 |
+
msgid "Display categories above products"
|
245 |
+
msgstr "Display categories above products"
|
246 |
|
247 |
msgid "Or you can add vertical categories to your website's toolbar using <a href=\"%s\">WordPress native widgets</a>"
|
248 |
msgstr "Puoi anche aggiungere alla barra degli strumenti le categorie verticali utilizzando i <a href=\"%s\">widgets nativi di WordPress</a>"
|
249 |
|
250 |
+
msgid "Enable minicart attached to categories"
|
251 |
+
msgstr "Enable minicart attached to categories"
|
252 |
|
253 |
msgid "You should disable this option, if you added minicart to your website's sidebar"
|
254 |
msgstr "È necessario disattivare questa opzione, se hai aggiunto il carrello al tuo sito web sidebar"
|
289 |
msgid "Connect your store<br /> to this WordPress site"
|
290 |
msgstr "Collega il tuo negozio<br /> a questo sito WordPress"
|
291 |
|
292 |
+
msgid "Enter your Store ID"
|
293 |
+
msgstr "Enter your Store ID"
|
294 |
+
|
295 |
msgid "Connect Ecwid store"
|
296 |
msgstr "Collega Ecwid store"
|
297 |
|
298 |
+
msgid "Save and connect"
|
299 |
+
msgstr "Save and connect"
|
300 |
+
|
301 |
msgid "After clicking button you need to login and accept permissions to use our plugin"
|
302 |
msgstr "Dopo aver cliccato il pulsante devi accedere e accettare le autorizzazioni necessarie per utilizzare il nostro plugin"
|
303 |
|
304 |
msgid "Connection error - after clicking button you need to login and accept permissions to use our plugin. Please, try again."
|
305 |
msgstr "Errore di connessione - dopo aver cliccato il pulsante, è necessario accedere e accettare le autorizzazioni necessarie per utilizzare il nostro plugin. Per favore, riprova."
|
306 |
|
307 |
+
msgid "Where to find your Store ID:"
|
308 |
+
msgstr "Where to find your Store ID:"
|
309 |
+
|
310 |
+
msgid "Store ID is a unique identifier of your Ecwid account. You can find it in your Ecwid control panel: open the <a %s>Dashboard page</a> and find the \"<b>Store ID: NNNNNNN</b>\" text, where <b>NNNNNNN</b> is your Store ID."
|
311 |
+
msgstr "Store ID is a unique identifier of your Ecwid account. You can find it in your Ecwid control panel: open the <a %s>Dashboard page</a> and find the \"<b>Store ID: NNNNNNN</b>\" text, where <b>NNNNNNN</b> is your Store ID."
|
312 |
+
|
313 |
msgid "Don't have Ecwid account? Create it here"
|
314 |
msgstr "Non hai un accont Ecwid? Crealo qui"
|
315 |
|
421 |
msgid "Free and always up to date"
|
422 |
msgstr "Gratuito e sempre aggiornato"
|
423 |
|
424 |
+
msgid "Free plan always available with tons of features<br>at no additional cost. Updates are seamless, automatic<br>and free of charge."
|
425 |
+
msgstr "Free plan always available with tons of features<br>at no additional cost. Updates are seamless, automatic<br>and free of charge."
|
426 |
|
427 |
msgid "Responsive design"
|
428 |
msgstr "Design eccezionale"
|
439 |
msgid "Global Reach"
|
440 |
msgstr "Portata globale"
|
441 |
|
442 |
+
msgid "More than 800,000 merchants in 175 countries"
|
443 |
+
msgstr "More than 800,000 merchants in 175 countries"
|
444 |
|
445 |
msgid "Start selling <br>on your WordPress <nobr>site for free</nobr>"
|
446 |
msgstr "Inizia a vendere <br>sul tuo WordPress <nobr>sito gratis</nobr>"
|
478 |
msgid "Show minicart"
|
479 |
msgstr "Mostra carrello"
|
480 |
|
481 |
+
msgid "Show categories"
|
482 |
+
msgstr "Show categories"
|
483 |
|
484 |
msgid "Additionally, you can add store controls to your website's toolbar using <a %s>WordPress native widgets</a>"
|
485 |
msgstr "Inoltre, è possibile aggiungere altri controlli alla barra degli strumenti del tuo sito Web utilizzando i <a %s>widgets nativi WordPress</a>"
|
496 |
msgid "Demo Store"
|
497 |
msgstr "Negozio demo"
|
498 |
|
499 |
+
msgid "Sell On The Go with Ecwid iOS Application"
|
500 |
+
msgstr "Sell On The Go with Ecwid iOS Application"
|
501 |
+
|
502 |
+
msgid "Ecwid iOS app allows you to manage your online store, sell your products on the go, and accept payments with your phone. Just download the Ecwid app, connect it to your Ecwid shop and have your sales at your fingertips!"
|
503 |
+
msgstr "Ecwid iOS app allows you to manage your online store, sell your products on the go, and accept payments with your phone. Just download the Ecwid app, connect it to your Ecwid shop and have your sales at your fingertips!"
|
504 |
+
|
505 |
+
msgid "Get Your Products Found on Google using XML Sitemap"
|
506 |
+
msgstr "Get Your Products Found on Google using XML Sitemap"
|
507 |
+
|
508 |
+
msgid "Free Google XML Sitemaps plugin creates a sitemap that includes your store product links. This makes your product pages more visible to search engines and appear in the search results."
|
509 |
+
msgstr "Free Google XML Sitemaps plugin creates a sitemap that includes your store product links. This makes your product pages more visible to search engines and appear in the search results."
|
510 |
+
|
511 |
+
msgid "Add Product Slider to Your Store"
|
512 |
+
msgstr "Add Product Slider to Your Store"
|
513 |
+
|
514 |
+
msgid "Add a fancy product slider to your site using a free WP Widgets Avalanche plugin which works perfectly with Ecwid"
|
515 |
+
msgstr "Add a fancy product slider to your site using a free WP Widgets Avalanche plugin which works perfectly with Ecwid"
|
516 |
+
|
languages/ecwid-shopping-cart-ru_RU.mo
CHANGED
Binary file
|
languages/ecwid-shopping-cart-ru_RU.po
CHANGED
@@ -280,8 +280,8 @@ msgstr "Ошибка подключения: после нажатия на кн
|
|
280 |
msgid "Don't have Ecwid account? Create it here"
|
281 |
msgstr "Ещё нет аккаунта в Эквиде? Зарегистрируйтесь"
|
282 |
|
283 |
-
msgid "Questions?
|
284 |
-
msgstr "Есть вопросы? Посетите <a %s>Центр поддержки Эквида (англ)</a> или <a
|
285 |
|
286 |
msgid "Store ID"
|
287 |
msgstr "ID Магазина"
|
280 |
msgid "Don't have Ecwid account? Create it here"
|
281 |
msgstr "Ещё нет аккаунта в Эквиде? Зарегистрируйтесь"
|
282 |
|
283 |
+
msgid "Questions? <a %s>Read FAQ</a> or contact support at <a %s>wordpress@ecwid.com</a>"
|
284 |
+
msgstr "Есть вопросы? Посетите <a %s>Центр поддержки Эквида (англ)</a> или напишите нам на <a %s>wordpress@ecwid.com</a>"
|
285 |
|
286 |
msgid "Store ID"
|
287 |
msgstr "ID Магазина"
|
languages/ecwid-shopping-cart-tr_TR.mo
CHANGED
Binary file
|
languages/ecwid-shopping-cart-tr_TR.po
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
msgid "Ecwid Shopping Cart"
|
2 |
-
msgstr "Ecwid
|
3 |
|
4 |
msgid "Ecwid Team"
|
5 |
msgstr "Ecwid Team"
|
6 |
|
7 |
msgid "Ecwid is a free full-featured shopping cart. It can be easily integrated with any Wordpress blog and takes less than 5 minutes to set up."
|
8 |
-
msgstr "Ecwid
|
9 |
|
10 |
msgid "Get help"
|
11 |
msgstr "Yardım alın"
|
@@ -35,13 +35,13 @@ msgid "Ecwid shopping cart settings"
|
|
35 |
msgstr "Ecwid alışveriş sepeti ayarları"
|
36 |
|
37 |
msgid "Ecwid Store"
|
38 |
-
msgstr "
|
39 |
|
40 |
msgid "Setup"
|
41 |
msgstr "Kurulum"
|
42 |
|
43 |
msgid "Dashboard"
|
44 |
-
msgstr "
|
45 |
|
46 |
msgid "Appearance settings"
|
47 |
msgstr "Görünüm ayarları"
|
@@ -58,8 +58,11 @@ msgstr "Gelişmiş"
|
|
58 |
msgid "Hidden category"
|
59 |
msgstr "Gizli kategori"
|
60 |
|
61 |
-
msgid "
|
62 |
-
msgstr "
|
|
|
|
|
|
|
63 |
|
64 |
msgid "Ecwid Badge"
|
65 |
msgstr "Ecwid Yaması"
|
@@ -79,42 +82,51 @@ msgstr "Ecwid alışveriş sepeti"
|
|
79 |
msgid "Ecwid e-commerce widgets"
|
80 |
msgstr "Ecwid e-ticaret widgetleri"
|
81 |
|
82 |
-
msgid "
|
83 |
-
msgstr "
|
84 |
|
85 |
-
msgid "
|
86 |
-
msgstr "
|
87 |
|
88 |
-
msgid "
|
89 |
-
msgstr "
|
90 |
|
91 |
-
msgid "
|
92 |
-
msgstr "
|
93 |
|
94 |
-
msgid "
|
95 |
-
msgstr "
|
96 |
|
97 |
-
msgid "
|
98 |
-
msgstr "
|
99 |
|
100 |
-
msgid "
|
101 |
-
msgstr "
|
102 |
|
103 |
-
msgid "
|
104 |
-
msgstr "
|
105 |
|
106 |
-
msgid "
|
107 |
-
msgstr "
|
|
|
|
|
|
|
108 |
|
109 |
msgid "Shop"
|
110 |
-
msgstr "
|
111 |
|
112 |
-
msgid "
|
113 |
-
msgstr "
|
114 |
|
115 |
msgid "Recently Viewed Products"
|
116 |
msgstr "Recently Viewed Products"
|
117 |
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
msgid "Number of products to show"
|
119 |
msgstr "Number of products to show"
|
120 |
|
@@ -161,13 +173,13 @@ msgid "Rate Ecwid at WordPress.org"
|
|
161 |
msgstr "WordPress.org sitesinde Ecwid uygulamasını oylayın"
|
162 |
|
163 |
msgid "Add Store"
|
164 |
-
msgstr "
|
165 |
|
166 |
msgid "Edit Store"
|
167 |
-
msgstr "
|
168 |
|
169 |
msgid "Edit Appearance"
|
170 |
-
msgstr "
|
171 |
|
172 |
msgid "Price"
|
173 |
msgstr "Fiyat"
|
@@ -199,8 +211,23 @@ msgstr "Tek giriş (Single Sign-On) Gizli Anahtarı"
|
|
199 |
msgid "Single Sign-On Secret Key is an option that allows your customers access to your WordPress site as well as the Ecwid shopping cart. When customers log in to your site, they will automatically be logged in to your Ecwid store as well. It makes sense to enable this feature if your visitors actually create accounts in your WordPress website."
|
200 |
msgstr "Tek giriş (Single Sign-On) gizli anahtarı müşterilerinizin WordPress sayfanızı Ecwid sayfanızı ziyaret eder gibi görüntülemelerini sağlar. Müşteriler sitenize giriş yaptıklarında otomatik olarak Ecwid mağazanıza da giriş yaparlar. Ziyaretçileriniz WordPress sayfanızda hesap oluşturmaya başladığında bu özelliği kullanabilirsiniz."
|
201 |
|
202 |
-
msgid "In order to enable this feature, opt to use a secret key. You will find this key in your Ecwid control panel, at \"System Settings > API > Single Sign-On
|
203 |
-
msgstr "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
|
205 |
msgid "Save changes"
|
206 |
msgstr "Değişiklikleri kaydet"
|
@@ -214,14 +241,14 @@ msgstr "Arama kutusunu ürünlerin üzerinde göster"
|
|
214 |
msgid "Or you can add search box to your website's toolbar using <a href=\"%s\">WordPress native widgets</a>"
|
215 |
msgstr "Ya da arama kutusunu <a href=\"%s\">WordPress yerleşik widgetlerını</a> kullanarak ekleyebilirsiniz"
|
216 |
|
217 |
-
msgid "Display
|
218 |
-
msgstr "
|
219 |
|
220 |
msgid "Or you can add vertical categories to your website's toolbar using <a href=\"%s\">WordPress native widgets</a>"
|
221 |
msgstr "Ya da dikey kategorileri sitenin araç çubuğuna <a href=\"%s\">WordPress yerleşik widgetlerını</a> kullanarak ekleyebilirsiniz"
|
222 |
|
223 |
-
msgid "Enable minicart attached to
|
224 |
-
msgstr "
|
225 |
|
226 |
msgid "You should disable this option, if you added minicart to your website's sidebar"
|
227 |
msgstr "Web sitenize küçük alışveriş sepeti eklediyseniz bu ayarı devre dışı bırakınız"
|
@@ -262,26 +289,38 @@ msgstr "Arama sonuçlarının varsayılan görünümü"
|
|
262 |
msgid "Connect your store<br /> to this WordPress site"
|
263 |
msgstr "Connect your store<br /> to this WordPress site"
|
264 |
|
|
|
|
|
|
|
265 |
msgid "Connect Ecwid store"
|
266 |
msgstr "Connect Ecwid store"
|
267 |
|
|
|
|
|
|
|
268 |
msgid "After clicking button you need to login and accept permissions to use our plugin"
|
269 |
-
msgstr "
|
270 |
|
271 |
msgid "Connection error - after clicking button you need to login and accept permissions to use our plugin. Please, try again."
|
272 |
-
msgstr "
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
|
274 |
msgid "Don't have Ecwid account? Create it here"
|
275 |
-
msgstr "
|
276 |
|
277 |
-
msgid "Questions? Visit <a
|
278 |
-
msgstr "
|
279 |
|
280 |
msgid "Store ID"
|
281 |
msgstr "Mağaza ID"
|
282 |
|
283 |
msgid "Disconnect store"
|
284 |
-
msgstr "
|
285 |
|
286 |
msgid "Congratulations!"
|
287 |
msgstr "Tebrikler!"
|
@@ -296,46 +335,46 @@ msgid "Your Ecwid store is connected<br /> to your WordPress website"
|
|
296 |
msgstr "Your Ecwid store is connected<br /> to your WordPress website"
|
297 |
|
298 |
msgid "Open control panel"
|
299 |
-
msgstr "
|
300 |
|
301 |
msgid "Plugin is installed successfully!"
|
302 |
-
msgstr "
|
303 |
|
304 |
-
msgid "There are just a few steps left to start selling<br />on your WordPress site"
|
305 |
-
msgstr "There are just a few steps left to start selling<br />on your WordPress site"
|
306 |
|
307 |
-
msgid "There are few little steps left to start selling<br />on your WordPress site"
|
308 |
-
msgstr "There are few little steps left to start selling<br />on your WordPress site"
|
309 |
|
310 |
msgid "Register"
|
311 |
-
msgstr "
|
312 |
|
313 |
-
msgid "Create a free Ecwid account to manage your
|
314 |
-
msgstr "Create a free Ecwid account to manage your
|
315 |
|
316 |
msgid "Connect"
|
317 |
-
msgstr "
|
318 |
|
319 |
-
msgid "Add your Ecwid store to your site<
|
320 |
-
msgstr "Add your Ecwid store to your site<
|
321 |
|
322 |
-
msgid "Connect your Ecwid store to this site<
|
323 |
-
msgstr "Connect your Ecwid store to this site<
|
324 |
|
325 |
msgid "Start selling"
|
326 |
-
msgstr "
|
327 |
|
328 |
msgid "Your storefront is ready"
|
329 |
msgstr "Your storefront is ready"
|
330 |
|
331 |
msgid "Create Ecwid store"
|
332 |
-
msgstr "
|
333 |
|
334 |
msgid "Connect your store"
|
335 |
-
msgstr "
|
336 |
|
337 |
msgid "Free registration, No credit card required"
|
338 |
-
msgstr "
|
339 |
|
340 |
msgid "Connection error: please click the button again and give permissions for this plugin<br /> to show your Ecwid store on this site."
|
341 |
msgstr "Connection error: please click the button again and give permissions for this plugin<br /> to show your Ecwid store on this site."
|
@@ -353,16 +392,16 @@ msgid "Don't have an Ecwid account?"
|
|
353 |
msgstr "Don't have an Ecwid account?"
|
354 |
|
355 |
msgid "Register at Ecwid for free"
|
356 |
-
msgstr "
|
357 |
|
358 |
msgid "No credit card required"
|
359 |
-
msgstr "
|
360 |
|
361 |
msgid "Get ready to sell online"
|
362 |
msgstr "Get ready to sell online"
|
363 |
|
364 |
msgid "Sell Everywhere<br>with your Ecwid store"
|
365 |
-
msgstr "
|
366 |
|
367 |
msgid "Start selling on your WordPress site. Then mirror your shop on your Facebook page, blog and marketplaces like Google Shopping, Yahoo and Shopping.com."
|
368 |
msgstr "Start selling on your WordPress site. Then mirror your shop on your Facebook page, blog and marketplaces like Google Shopping, Yahoo and Shopping.com."
|
@@ -376,14 +415,14 @@ msgstr "Features"
|
|
376 |
msgid "Compatible with your theme"
|
377 |
msgstr "Compatible with your theme"
|
378 |
|
379 |
-
msgid "Ecwid is compatible with your<br
|
380 |
-
msgstr "Ecwid is compatible with your<br
|
381 |
|
382 |
msgid "Free and always up to date"
|
383 |
msgstr "Free and always up to date"
|
384 |
|
385 |
-
msgid "Free plan always available with tons of features<br>at no additional cost.
|
386 |
-
msgstr "Free plan always available with tons of features<br>at no additional cost.
|
387 |
|
388 |
msgid "Responsive design"
|
389 |
msgstr "Responsive design"
|
@@ -400,8 +439,8 @@ msgstr "Secure checkout with over 40<br />payment options"
|
|
400 |
msgid "Global Reach"
|
401 |
msgstr "Global Reach"
|
402 |
|
403 |
-
msgid "More than
|
404 |
-
msgstr "More than
|
405 |
|
406 |
msgid "Start selling <br>on your WordPress <nobr>site for free</nobr>"
|
407 |
msgstr "Start selling <br>on your WordPress <nobr>site for free</nobr>"
|
@@ -421,8 +460,8 @@ msgstr "Reconnect Ecwid store"
|
|
421 |
msgid "New features available, reconnect to be in touch with our updates"
|
422 |
msgstr "New features available, reconnect to be in touch with our updates"
|
423 |
|
424 |
-
msgid "
|
425 |
-
msgstr "
|
426 |
|
427 |
msgid "Store settings"
|
428 |
msgstr "Store settings"
|
@@ -439,8 +478,8 @@ msgstr "Show search"
|
|
439 |
msgid "Show minicart"
|
440 |
msgstr "Show minicart"
|
441 |
|
442 |
-
msgid "Show
|
443 |
-
msgstr "Show
|
444 |
|
445 |
msgid "Additionally, you can add store controls to your website's toolbar using <a %s>WordPress native widgets</a>"
|
446 |
msgstr "Additionally, you can add store controls to your website's toolbar using <a %s>WordPress native widgets</a>"
|
@@ -451,12 +490,27 @@ msgstr "Demo store"
|
|
451 |
msgid "Ecwid plugin settings"
|
452 |
msgstr "Ecwid plugin settings"
|
453 |
|
454 |
-
msgid "Save and close"
|
455 |
-
msgstr "Save and close"
|
456 |
-
|
457 |
msgid "Your store will be shown here!"
|
458 |
-
msgstr "
|
459 |
|
460 |
msgid "Demo Store"
|
461 |
-
msgstr "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
462 |
|
1 |
msgid "Ecwid Shopping Cart"
|
2 |
+
msgstr "Ecwid alışveriş sepeti"
|
3 |
|
4 |
msgid "Ecwid Team"
|
5 |
msgstr "Ecwid Team"
|
6 |
|
7 |
msgid "Ecwid is a free full-featured shopping cart. It can be easily integrated with any Wordpress blog and takes less than 5 minutes to set up."
|
8 |
+
msgstr "Ecwid, ücretsiz ve tam özellikli bir alışveriş sepetidir. Beş dakikadan daha kısa bir sürede kurulabilir ve her hangi bir Wordpress bloğuyla bütünleştirilebilir."
|
9 |
|
10 |
msgid "Get help"
|
11 |
msgstr "Yardım alın"
|
35 |
msgstr "Ecwid alışveriş sepeti ayarları"
|
36 |
|
37 |
msgid "Ecwid Store"
|
38 |
+
msgstr "Eсwid Mağazası"
|
39 |
|
40 |
msgid "Setup"
|
41 |
msgstr "Kurulum"
|
42 |
|
43 |
msgid "Dashboard"
|
44 |
+
msgstr "Kontrol paneli"
|
45 |
|
46 |
msgid "Appearance settings"
|
47 |
msgstr "Görünüm ayarları"
|
58 |
msgid "Hidden category"
|
59 |
msgstr "Gizli kategori"
|
60 |
|
61 |
+
msgid "Recommendations for Your Online Store"
|
62 |
+
msgstr "Çevrimiçi Mağazanız için Öneriler"
|
63 |
+
|
64 |
+
msgid "Do you like Ecwid and want to help it grow? You can add this fancy 'Powered by Ecwid' badge on your site to show your visitors that you're a proud user of Ecwid."
|
65 |
+
msgstr "Do you like Ecwid and want to help it grow? You can add this fancy 'Powered by Ecwid' badge on your site to show your visitors that you're a proud user of Ecwid."
|
66 |
|
67 |
msgid "Ecwid Badge"
|
68 |
msgstr "Ecwid Yaması"
|
82 |
msgid "Ecwid e-commerce widgets"
|
83 |
msgstr "Ecwid e-ticaret widgetleri"
|
84 |
|
85 |
+
msgid "Adds a cart widget for customer to see the products they added to the cart."
|
86 |
+
msgstr "Adds a cart widget for customer to see the products they added to the cart."
|
87 |
|
88 |
+
msgid "Shopping Cart"
|
89 |
+
msgstr "Shopping Cart"
|
90 |
|
91 |
+
msgid "Adds a compact cart widget for customer to see the products they added to the cart."
|
92 |
+
msgstr "Adds a compact cart widget for customer to see the products they added to the cart."
|
93 |
|
94 |
+
msgid "Shopping Cart (Mini)"
|
95 |
+
msgstr "Shopping Cart (Mini)"
|
96 |
|
97 |
+
msgid "Displays a simple search box for your customers to find a product in your storex"
|
98 |
+
msgstr "Displays a simple search box for your customers to find a product in your storex"
|
99 |
|
100 |
+
msgid "Product Search"
|
101 |
+
msgstr "Product Search"
|
102 |
|
103 |
+
msgid "Adds vertical categories block to let the customer navigate your store."
|
104 |
+
msgstr "Adds vertical categories block to let the customer navigate your store."
|
105 |
|
106 |
+
msgid "Store Categories"
|
107 |
+
msgstr "Store Categories"
|
108 |
|
109 |
+
msgid "Displays a link to the store page in sidebar for customer to quickly access your store from any page on the site."
|
110 |
+
msgstr "Displays a link to the store page in sidebar for customer to quickly access your store from any page on the site."
|
111 |
+
|
112 |
+
msgid "Store Page Link"
|
113 |
+
msgstr "Store Page Link"
|
114 |
|
115 |
msgid "Shop"
|
116 |
+
msgstr "Mağaza"
|
117 |
|
118 |
+
msgid "Displays a list of products recently viewed by the customer to easily return to the products they saw in your shop."
|
119 |
+
msgstr "Displays a list of products recently viewed by the customer to easily return to the products they saw in your shop."
|
120 |
|
121 |
msgid "Recently Viewed Products"
|
122 |
msgstr "Recently Viewed Products"
|
123 |
|
124 |
+
msgid "You have not viewed any product yet. Open store."
|
125 |
+
msgstr "You have not viewed any product yet. Open store."
|
126 |
+
|
127 |
+
msgid "Store Link Title"
|
128 |
+
msgstr "Store Link Title"
|
129 |
+
|
130 |
msgid "Number of products to show"
|
131 |
msgstr "Number of products to show"
|
132 |
|
173 |
msgstr "WordPress.org sitesinde Ecwid uygulamasını oylayın"
|
174 |
|
175 |
msgid "Add Store"
|
176 |
+
msgstr "Mağaza Ekle"
|
177 |
|
178 |
msgid "Edit Store"
|
179 |
+
msgstr "Mağazayı Düzenle"
|
180 |
|
181 |
msgid "Edit Appearance"
|
182 |
+
msgstr "Görünümü Düzenle"
|
183 |
|
184 |
msgid "Price"
|
185 |
msgstr "Fiyat"
|
211 |
msgid "Single Sign-On Secret Key is an option that allows your customers access to your WordPress site as well as the Ecwid shopping cart. When customers log in to your site, they will automatically be logged in to your Ecwid store as well. It makes sense to enable this feature if your visitors actually create accounts in your WordPress website."
|
212 |
msgstr "Tek giriş (Single Sign-On) gizli anahtarı müşterilerinizin WordPress sayfanızı Ecwid sayfanızı ziyaret eder gibi görüntülemelerini sağlar. Müşteriler sitenize giriş yaptıklarında otomatik olarak Ecwid mağazanıza da giriş yaparlar. Ziyaretçileriniz WordPress sayfanızda hesap oluşturmaya başladığında bu özelliği kullanabilirsiniz."
|
213 |
|
214 |
+
msgid "In order to enable this feature, opt to use a secret key. You will find this key in your Ecwid control panel, at \"System Settings > Apps > Legacy API Keys > Single Sign-On Secret Key\" page. This feature is available for <a href=\"http://www.ecwid.com/compare-plans.html\" target=\"_blank\">paid users</a> only."
|
215 |
+
msgstr "In order to enable this feature, opt to use a secret key. You will find this key in your Ecwid control panel, at \"System Settings > Apps > Legacy API Keys > Single Sign-On Secret Key\" page. This feature is available for <a href=\"http://www.ecwid.com/compare-plans.html\" target=\"_blank\">paid users</a> only."
|
216 |
+
|
217 |
+
msgid "Chameleon skin <sup>beta</sup>"
|
218 |
+
msgstr "Chameleon skin <sup>beta</sup>"
|
219 |
+
|
220 |
+
msgid "Automatic adjustment of your store design to your Wordpress theme. Whatever Wordpress theme you use, Ecwid will detect predominant colors and font and use them in your product catalog."
|
221 |
+
msgstr "Automatic adjustment of your store design to your Wordpress theme. Whatever Wordpress theme you use, Ecwid will detect predominant colors and font and use them in your product catalog."
|
222 |
+
|
223 |
+
msgid "Please note this functionality is in beta. So if you run into difficulties or find problems with Chameleon, please <a %s>let us know</a>."
|
224 |
+
msgstr "Please note this functionality is in beta. So if you run into difficulties or find problems with Chameleon, please <a %s>let us know</a>."
|
225 |
+
|
226 |
+
msgid "Enable the new category menu"
|
227 |
+
msgstr "Enable the new category menu"
|
228 |
+
|
229 |
+
msgid "The new category menu looks better and is more mobile-friendly. If you haven't yet added category menu to your store page, you can do that in the <a %s>store page editor</a> (enable the \"Show categories\" option)"
|
230 |
+
msgstr "The new category menu looks better and is more mobile-friendly. If you haven't yet added category menu to your store page, you can do that in the <a %s>store page editor</a> (enable the \"Show categories\" option)"
|
231 |
|
232 |
msgid "Save changes"
|
233 |
msgstr "Değişiklikleri kaydet"
|
241 |
msgid "Or you can add search box to your website's toolbar using <a href=\"%s\">WordPress native widgets</a>"
|
242 |
msgstr "Ya da arama kutusunu <a href=\"%s\">WordPress yerleşik widgetlerını</a> kullanarak ekleyebilirsiniz"
|
243 |
|
244 |
+
msgid "Display categories above products"
|
245 |
+
msgstr "Display categories above products"
|
246 |
|
247 |
msgid "Or you can add vertical categories to your website's toolbar using <a href=\"%s\">WordPress native widgets</a>"
|
248 |
msgstr "Ya da dikey kategorileri sitenin araç çubuğuna <a href=\"%s\">WordPress yerleşik widgetlerını</a> kullanarak ekleyebilirsiniz"
|
249 |
|
250 |
+
msgid "Enable minicart attached to categories"
|
251 |
+
msgstr "Enable minicart attached to categories"
|
252 |
|
253 |
msgid "You should disable this option, if you added minicart to your website's sidebar"
|
254 |
msgstr "Web sitenize küçük alışveriş sepeti eklediyseniz bu ayarı devre dışı bırakınız"
|
289 |
msgid "Connect your store<br /> to this WordPress site"
|
290 |
msgstr "Connect your store<br /> to this WordPress site"
|
291 |
|
292 |
+
msgid "Enter your Store ID"
|
293 |
+
msgstr "Enter your Store ID"
|
294 |
+
|
295 |
msgid "Connect Ecwid store"
|
296 |
msgstr "Connect Ecwid store"
|
297 |
|
298 |
+
msgid "Save and connect"
|
299 |
+
msgstr "Save and connect"
|
300 |
+
|
301 |
msgid "After clicking button you need to login and accept permissions to use our plugin"
|
302 |
+
msgstr "Düğmeye tıkladıktan sonra eklentiyi kullanmak için giriş yapıp izinleri onaylamalısınız"
|
303 |
|
304 |
msgid "Connection error - after clicking button you need to login and accept permissions to use our plugin. Please, try again."
|
305 |
+
msgstr "Bağlantı hatası - düğmeye tıkladıktan sonra eklentiyi kullanmak için giriş yapıp izinleri onaylamalısınız. Lütfen tekrar deneyin."
|
306 |
+
|
307 |
+
msgid "Where to find your Store ID:"
|
308 |
+
msgstr "Where to find your Store ID:"
|
309 |
+
|
310 |
+
msgid "Store ID is a unique identifier of your Ecwid account. You can find it in your Ecwid control panel: open the <a %s>Dashboard page</a> and find the \"<b>Store ID: NNNNNNN</b>\" text, where <b>NNNNNNN</b> is your Store ID."
|
311 |
+
msgstr "Store ID is a unique identifier of your Ecwid account. You can find it in your Ecwid control panel: open the <a %s>Dashboard page</a> and find the \"<b>Store ID: NNNNNNN</b>\" text, where <b>NNNNNNN</b> is your Store ID."
|
312 |
|
313 |
msgid "Don't have Ecwid account? Create it here"
|
314 |
+
msgstr "Ecwid hesabınız yok mu? Burada oluşturun"
|
315 |
|
316 |
+
msgid "Questions? Visit <a %s>Ecwid support center</a>"
|
317 |
+
msgstr "Questions? Visit <a %s>Ecwid support center</a>"
|
318 |
|
319 |
msgid "Store ID"
|
320 |
msgstr "Mağaza ID"
|
321 |
|
322 |
msgid "Disconnect store"
|
323 |
+
msgstr "Mağaza bağlantısını kes"
|
324 |
|
325 |
msgid "Congratulations!"
|
326 |
msgstr "Tebrikler!"
|
335 |
msgstr "Your Ecwid store is connected<br /> to your WordPress website"
|
336 |
|
337 |
msgid "Open control panel"
|
338 |
+
msgstr "Kontrol panelini aç"
|
339 |
|
340 |
msgid "Plugin is installed successfully!"
|
341 |
+
msgstr "Eklenti başarıyla yüklendi!"
|
342 |
|
343 |
+
msgid "There are just a few steps left to start selling<br /> on your WordPress site"
|
344 |
+
msgstr "There are just a few steps left to start selling<br /> on your WordPress site"
|
345 |
|
346 |
+
msgid "There are few little steps left to start selling<br /> on your WordPress site"
|
347 |
+
msgstr "There are few little steps left to start selling<br /> on your WordPress site"
|
348 |
|
349 |
msgid "Register"
|
350 |
+
msgstr "Kayıt Ol"
|
351 |
|
352 |
+
msgid "Create a free Ecwid account to manage your store and inventory.<br /> No credit card required"
|
353 |
+
msgstr "Create a free Ecwid account to manage your store and inventory.<br /> No credit card required"
|
354 |
|
355 |
msgid "Connect"
|
356 |
+
msgstr "Bağlan"
|
357 |
|
358 |
+
msgid "Add your Ecwid store to your site <nobr>in two clicks</nobr>"
|
359 |
+
msgstr "Add your Ecwid store to your site <nobr>in two clicks</nobr>"
|
360 |
|
361 |
+
msgid "Connect your Ecwid store to this site <nobr>in two clicks</nobr>"
|
362 |
+
msgstr "Connect your Ecwid store to this site <nobr>in two clicks</nobr>"
|
363 |
|
364 |
msgid "Start selling"
|
365 |
+
msgstr "Satmaya başlayın"
|
366 |
|
367 |
msgid "Your storefront is ready"
|
368 |
msgstr "Your storefront is ready"
|
369 |
|
370 |
msgid "Create Ecwid store"
|
371 |
+
msgstr "Ecwid Mağazası oluştur"
|
372 |
|
373 |
msgid "Connect your store"
|
374 |
+
msgstr "Mağazanızı bağlayın"
|
375 |
|
376 |
msgid "Free registration, No credit card required"
|
377 |
+
msgstr "Ücretsiz kayıt, kredi kartı gerekli değil"
|
378 |
|
379 |
msgid "Connection error: please click the button again and give permissions for this plugin<br /> to show your Ecwid store on this site."
|
380 |
msgstr "Connection error: please click the button again and give permissions for this plugin<br /> to show your Ecwid store on this site."
|
392 |
msgstr "Don't have an Ecwid account?"
|
393 |
|
394 |
msgid "Register at Ecwid for free"
|
395 |
+
msgstr "Ecwid'e ücretsiz kayıt olun"
|
396 |
|
397 |
msgid "No credit card required"
|
398 |
+
msgstr "Kredi kartı gerekmez"
|
399 |
|
400 |
msgid "Get ready to sell online"
|
401 |
msgstr "Get ready to sell online"
|
402 |
|
403 |
msgid "Sell Everywhere<br>with your Ecwid store"
|
404 |
+
msgstr "Ecwid mağazası<br>ile Her Yerde Satın"
|
405 |
|
406 |
msgid "Start selling on your WordPress site. Then mirror your shop on your Facebook page, blog and marketplaces like Google Shopping, Yahoo and Shopping.com."
|
407 |
msgstr "Start selling on your WordPress site. Then mirror your shop on your Facebook page, blog and marketplaces like Google Shopping, Yahoo and Shopping.com."
|
415 |
msgid "Compatible with your theme"
|
416 |
msgstr "Compatible with your theme"
|
417 |
|
418 |
+
msgid "Ecwid is compatible with your<br>“%s” WordPress theme<br>out of the box."
|
419 |
+
msgstr "Ecwid is compatible with your<br>“%s” WordPress theme<br>out of the box."
|
420 |
|
421 |
msgid "Free and always up to date"
|
422 |
msgstr "Free and always up to date"
|
423 |
|
424 |
+
msgid "Free plan always available with tons of features<br>at no additional cost. Updates are seamless, automatic<br>and free of charge."
|
425 |
+
msgstr "Free plan always available with tons of features<br>at no additional cost. Updates are seamless, automatic<br>and free of charge."
|
426 |
|
427 |
msgid "Responsive design"
|
428 |
msgstr "Responsive design"
|
439 |
msgid "Global Reach"
|
440 |
msgstr "Global Reach"
|
441 |
|
442 |
+
msgid "More than 800,000 merchants in 175 countries"
|
443 |
+
msgstr "More than 800,000 merchants in 175 countries"
|
444 |
|
445 |
msgid "Start selling <br>on your WordPress <nobr>site for free</nobr>"
|
446 |
msgstr "Start selling <br>on your WordPress <nobr>site for free</nobr>"
|
460 |
msgid "New features available, reconnect to be in touch with our updates"
|
461 |
msgstr "New features available, reconnect to be in touch with our updates"
|
462 |
|
463 |
+
msgid "Questions? Visit <a href=\"http://help.ecwid.com/?source=wporg\">Ecwid support center</a>"
|
464 |
+
msgstr "Sorun mu yaşıyorsunuz? <a href=\"http://help.ecwid.com/?source=wporg\">Ecwid destek merkezini</a> ziyaret edin"
|
465 |
|
466 |
msgid "Store settings"
|
467 |
msgstr "Store settings"
|
478 |
msgid "Show minicart"
|
479 |
msgstr "Show minicart"
|
480 |
|
481 |
+
msgid "Show categories"
|
482 |
+
msgstr "Show categories"
|
483 |
|
484 |
msgid "Additionally, you can add store controls to your website's toolbar using <a %s>WordPress native widgets</a>"
|
485 |
msgstr "Additionally, you can add store controls to your website's toolbar using <a %s>WordPress native widgets</a>"
|
490 |
msgid "Ecwid plugin settings"
|
491 |
msgstr "Ecwid plugin settings"
|
492 |
|
|
|
|
|
|
|
493 |
msgid "Your store will be shown here!"
|
494 |
+
msgstr "Mağazanız burada görünecek!"
|
495 |
|
496 |
msgid "Demo Store"
|
497 |
+
msgstr "Deneme mağazası"
|
498 |
+
|
499 |
+
msgid "Sell On The Go with Ecwid iOS Application"
|
500 |
+
msgstr "Ecwid iOS uygulamasıyla Hareket Halinde Satın"
|
501 |
+
|
502 |
+
msgid "Ecwid iOS app allows you to manage your online store, sell your products on the go, and accept payments with your phone. Just download the Ecwid app, connect it to your Ecwid shop and have your sales at your fingertips!"
|
503 |
+
msgstr "Ecwid iOS app allows you to manage your online store, sell your products on the go, and accept payments with your phone. Just download the Ecwid app, connect it to your Ecwid shop and have your sales at your fingertips!"
|
504 |
+
|
505 |
+
msgid "Get Your Products Found on Google using XML Sitemap"
|
506 |
+
msgstr "Get Your Products Found on Google using XML Sitemap"
|
507 |
+
|
508 |
+
msgid "Free Google XML Sitemaps plugin creates a sitemap that includes your store product links. This makes your product pages more visible to search engines and appear in the search results."
|
509 |
+
msgstr "Free Google XML Sitemaps plugin creates a sitemap that includes your store product links. This makes your product pages more visible to search engines and appear in the search results."
|
510 |
+
|
511 |
+
msgid "Add Product Slider to Your Store"
|
512 |
+
msgstr "Mağazanıza Ürün Kaydırıcı Ekleyin"
|
513 |
+
|
514 |
+
msgid "Add a fancy product slider to your site using a free WP Widgets Avalanche plugin which works perfectly with Ecwid"
|
515 |
+
msgstr "Ecwid ile mükemmel bir şekilde çalışan WP Widgets Avalanche eklentisini indirerek sitenize süslü bir ürün kaydırıcısı ekleyin"
|
516 |
|
lib/phpseclib/AES.php
ADDED
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Pure-PHP implementation of AES.
|
5 |
+
*
|
6 |
+
* Uses mcrypt, if available/possible, and an internal implementation, otherwise.
|
7 |
+
*
|
8 |
+
* PHP versions 4 and 5
|
9 |
+
*
|
10 |
+
* NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
|
11 |
+
* just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
|
12 |
+
* to save one include_once().
|
13 |
+
*
|
14 |
+
* If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
15 |
+
* {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
|
16 |
+
* it'll be null-padded to 192-bits and 192 bits will be the key length until {@link Crypt_AES::setKey() setKey()}
|
17 |
+
* is called, again, at which point, it'll be recalculated.
|
18 |
+
*
|
19 |
+
* Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
|
20 |
+
* make a whole lot of sense. {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance. Calling that function,
|
21 |
+
* however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
|
22 |
+
*
|
23 |
+
* Here's a short example of how to use this library:
|
24 |
+
* <code>
|
25 |
+
* <?php
|
26 |
+
* include 'Crypt/AES.php';
|
27 |
+
*
|
28 |
+
* $aes = new Crypt_AES();
|
29 |
+
*
|
30 |
+
* $aes->setKey('abcdefghijklmnop');
|
31 |
+
*
|
32 |
+
* $size = 10 * 1024;
|
33 |
+
* $plaintext = '';
|
34 |
+
* for ($i = 0; $i < $size; $i++) {
|
35 |
+
* $plaintext.= 'a';
|
36 |
+
* }
|
37 |
+
*
|
38 |
+
* echo $aes->decrypt($aes->encrypt($plaintext));
|
39 |
+
* ?>
|
40 |
+
* </code>
|
41 |
+
*
|
42 |
+
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
43 |
+
* of this software and associated documentation files (the "Software"), to deal
|
44 |
+
* in the Software without restriction, including without limitation the rights
|
45 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
46 |
+
* copies of the Software, and to permit persons to whom the Software is
|
47 |
+
* furnished to do so, subject to the following conditions:
|
48 |
+
*
|
49 |
+
* The above copyright notice and this permission notice shall be included in
|
50 |
+
* all copies or substantial portions of the Software.
|
51 |
+
*
|
52 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
53 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
54 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
55 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
56 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
57 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
58 |
+
* THE SOFTWARE.
|
59 |
+
*
|
60 |
+
* @category Crypt
|
61 |
+
* @package Crypt_AES
|
62 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
63 |
+
* @copyright 2008 Jim Wigginton
|
64 |
+
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
65 |
+
* @link http://phpseclib.sourceforge.net
|
66 |
+
*/
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Include Crypt_Rijndael
|
70 |
+
*/
|
71 |
+
if (!class_exists('Crypt_Rijndael')) {
|
72 |
+
include_once 'Rijndael.php';
|
73 |
+
}
|
74 |
+
|
75 |
+
/**#@+
|
76 |
+
* @access public
|
77 |
+
* @see Crypt_AES::encrypt()
|
78 |
+
* @see Crypt_AES::decrypt()
|
79 |
+
*/
|
80 |
+
/**
|
81 |
+
* Encrypt / decrypt using the Counter mode.
|
82 |
+
*
|
83 |
+
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
84 |
+
*
|
85 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
86 |
+
*/
|
87 |
+
define('CRYPT_AES_MODE_CTR', CRYPT_MODE_CTR);
|
88 |
+
/**
|
89 |
+
* Encrypt / decrypt using the Electronic Code Book mode.
|
90 |
+
*
|
91 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
92 |
+
*/
|
93 |
+
define('CRYPT_AES_MODE_ECB', CRYPT_MODE_ECB);
|
94 |
+
/**
|
95 |
+
* Encrypt / decrypt using the Code Book Chaining mode.
|
96 |
+
*
|
97 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
98 |
+
*/
|
99 |
+
define('CRYPT_AES_MODE_CBC', CRYPT_MODE_CBC);
|
100 |
+
/**
|
101 |
+
* Encrypt / decrypt using the Cipher Feedback mode.
|
102 |
+
*
|
103 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
104 |
+
*/
|
105 |
+
define('CRYPT_AES_MODE_CFB', CRYPT_MODE_CFB);
|
106 |
+
/**
|
107 |
+
* Encrypt / decrypt using the Cipher Feedback mode.
|
108 |
+
*
|
109 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
110 |
+
*/
|
111 |
+
define('CRYPT_AES_MODE_OFB', CRYPT_MODE_OFB);
|
112 |
+
/**#@-*/
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Pure-PHP implementation of AES.
|
116 |
+
*
|
117 |
+
* @package Crypt_AES
|
118 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
119 |
+
* @access public
|
120 |
+
*/
|
121 |
+
class Crypt_AES extends Crypt_Rijndael
|
122 |
+
{
|
123 |
+
/**
|
124 |
+
* The namespace used by the cipher for its constants.
|
125 |
+
*
|
126 |
+
* @see Crypt_Base::const_namespace
|
127 |
+
* @var string
|
128 |
+
* @access private
|
129 |
+
*/
|
130 |
+
var $const_namespace = 'AES';
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Dummy function
|
134 |
+
*
|
135 |
+
* Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
|
136 |
+
*
|
137 |
+
* @see Crypt_Rijndael::setBlockLength()
|
138 |
+
* @access public
|
139 |
+
* @param int $length
|
140 |
+
*/
|
141 |
+
function setBlockLength($length)
|
142 |
+
{
|
143 |
+
return;
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Sets the key length
|
148 |
+
*
|
149 |
+
* Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to
|
150 |
+
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
|
151 |
+
*
|
152 |
+
* @see Crypt_Rijndael:setKeyLength()
|
153 |
+
* @access public
|
154 |
+
* @param int $length
|
155 |
+
*/
|
156 |
+
function setKeyLength($length)
|
157 |
+
{
|
158 |
+
switch ($length) {
|
159 |
+
case 160:
|
160 |
+
$length = 192;
|
161 |
+
break;
|
162 |
+
case 224:
|
163 |
+
$length = 256;
|
164 |
+
}
|
165 |
+
parent::setKeyLength($length);
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Sets the key.
|
170 |
+
*
|
171 |
+
* Rijndael supports five different key lengths, AES only supports three.
|
172 |
+
*
|
173 |
+
* @see Crypt_Rijndael:setKey()
|
174 |
+
* @see setKeyLength()
|
175 |
+
* @access public
|
176 |
+
* @param string $key
|
177 |
+
*/
|
178 |
+
function setKey($key)
|
179 |
+
{
|
180 |
+
parent::setKey($key);
|
181 |
+
|
182 |
+
if (!$this->explicit_key_length) {
|
183 |
+
$length = strlen($key);
|
184 |
+
switch (true) {
|
185 |
+
case $length <= 16:
|
186 |
+
$this->key_length = 16;
|
187 |
+
break;
|
188 |
+
case $length <= 24:
|
189 |
+
$this->key_length = 24;
|
190 |
+
break;
|
191 |
+
default:
|
192 |
+
$this->key_length = 32;
|
193 |
+
}
|
194 |
+
$this->_setEngine();
|
195 |
+
}
|
196 |
+
}
|
197 |
+
}
|
lib/phpseclib/Base.php
ADDED
@@ -0,0 +1,2593 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Base Class for all Crypt_* cipher classes
|
5 |
+
*
|
6 |
+
* PHP versions 4 and 5
|
7 |
+
*
|
8 |
+
* Internally for phpseclib developers:
|
9 |
+
* If you plan to add a new cipher class, please note following rules:
|
10 |
+
*
|
11 |
+
* - The new Crypt_* cipher class should extend Crypt_Base
|
12 |
+
*
|
13 |
+
* - Following methods are then required to be overridden/overloaded:
|
14 |
+
*
|
15 |
+
* - _encryptBlock()
|
16 |
+
*
|
17 |
+
* - _decryptBlock()
|
18 |
+
*
|
19 |
+
* - _setupKey()
|
20 |
+
*
|
21 |
+
* - All other methods are optional to be overridden/overloaded
|
22 |
+
*
|
23 |
+
* - Look at the source code of the current ciphers how they extend Crypt_Base
|
24 |
+
* and take one of them as a start up for the new cipher class.
|
25 |
+
*
|
26 |
+
* - Please read all the other comments/notes/hints here also for each class var/method
|
27 |
+
*
|
28 |
+
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
29 |
+
* of this software and associated documentation files (the "Software"), to deal
|
30 |
+
* in the Software without restriction, including without limitation the rights
|
31 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
32 |
+
* copies of the Software, and to permit persons to whom the Software is
|
33 |
+
* furnished to do so, subject to the following conditions:
|
34 |
+
*
|
35 |
+
* The above copyright notice and this permission notice shall be included in
|
36 |
+
* all copies or substantial portions of the Software.
|
37 |
+
*
|
38 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
39 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
40 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
41 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
42 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
43 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
44 |
+
* THE SOFTWARE.
|
45 |
+
*
|
46 |
+
* @category Crypt
|
47 |
+
* @package Crypt_Base
|
48 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
49 |
+
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
50 |
+
* @copyright 2007 Jim Wigginton
|
51 |
+
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
52 |
+
* @link http://phpseclib.sourceforge.net
|
53 |
+
*/
|
54 |
+
|
55 |
+
/**#@+
|
56 |
+
* @access public
|
57 |
+
* @see Crypt_Base::encrypt()
|
58 |
+
* @see Crypt_Base::decrypt()
|
59 |
+
*/
|
60 |
+
/**
|
61 |
+
* Encrypt / decrypt using the Counter mode.
|
62 |
+
*
|
63 |
+
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
64 |
+
*
|
65 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
66 |
+
*/
|
67 |
+
define('CRYPT_MODE_CTR', -1);
|
68 |
+
/**
|
69 |
+
* Encrypt / decrypt using the Electronic Code Book mode.
|
70 |
+
*
|
71 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
72 |
+
*/
|
73 |
+
define('CRYPT_MODE_ECB', 1);
|
74 |
+
/**
|
75 |
+
* Encrypt / decrypt using the Code Book Chaining mode.
|
76 |
+
*
|
77 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
78 |
+
*/
|
79 |
+
define('CRYPT_MODE_CBC', 2);
|
80 |
+
/**
|
81 |
+
* Encrypt / decrypt using the Cipher Feedback mode.
|
82 |
+
*
|
83 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
84 |
+
*/
|
85 |
+
define('CRYPT_MODE_CFB', 3);
|
86 |
+
/**
|
87 |
+
* Encrypt / decrypt using the Output Feedback mode.
|
88 |
+
*
|
89 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
90 |
+
*/
|
91 |
+
define('CRYPT_MODE_OFB', 4);
|
92 |
+
/**
|
93 |
+
* Encrypt / decrypt using streaming mode.
|
94 |
+
*/
|
95 |
+
define('CRYPT_MODE_STREAM', 5);
|
96 |
+
/**#@-*/
|
97 |
+
|
98 |
+
/**#@+
|
99 |
+
* @access private
|
100 |
+
* @see Crypt_Base::Crypt_Base()
|
101 |
+
* @internal These constants are for internal use only
|
102 |
+
*/
|
103 |
+
/**
|
104 |
+
* Base value for the internal implementation $engine switch
|
105 |
+
*/
|
106 |
+
define('CRYPT_ENGINE_INTERNAL', 1);
|
107 |
+
/**
|
108 |
+
* Base value for the mcrypt implementation $engine switch
|
109 |
+
*/
|
110 |
+
define('CRYPT_ENGINE_MCRYPT', 2);
|
111 |
+
/**
|
112 |
+
* Base value for the OpenSSL implementation $engine switch
|
113 |
+
*/
|
114 |
+
define('CRYPT_ENGINE_OPENSSL', 3);
|
115 |
+
/**#@-*/
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Base Class for all Crypt_* cipher classes
|
119 |
+
*
|
120 |
+
* @package Crypt_Base
|
121 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
122 |
+
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
123 |
+
* @access public
|
124 |
+
*/
|
125 |
+
class Crypt_Base
|
126 |
+
{
|
127 |
+
/**
|
128 |
+
* The Encryption Mode
|
129 |
+
*
|
130 |
+
* @see Crypt_Base::Crypt_Base()
|
131 |
+
* @var int
|
132 |
+
* @access private
|
133 |
+
*/
|
134 |
+
var $mode;
|
135 |
+
|
136 |
+
/**
|
137 |
+
* The Block Length of the block cipher
|
138 |
+
*
|
139 |
+
* @var int
|
140 |
+
* @access private
|
141 |
+
*/
|
142 |
+
var $block_size = 16;
|
143 |
+
|
144 |
+
/**
|
145 |
+
* The Key
|
146 |
+
*
|
147 |
+
* @see Crypt_Base::setKey()
|
148 |
+
* @var string
|
149 |
+
* @access private
|
150 |
+
*/
|
151 |
+
var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
152 |
+
|
153 |
+
/**
|
154 |
+
* The Initialization Vector
|
155 |
+
*
|
156 |
+
* @see Crypt_Base::setIV()
|
157 |
+
* @var string
|
158 |
+
* @access private
|
159 |
+
*/
|
160 |
+
var $iv;
|
161 |
+
|
162 |
+
/**
|
163 |
+
* A "sliding" Initialization Vector
|
164 |
+
*
|
165 |
+
* @see Crypt_Base::enableContinuousBuffer()
|
166 |
+
* @see Crypt_Base::_clearBuffers()
|
167 |
+
* @var string
|
168 |
+
* @access private
|
169 |
+
*/
|
170 |
+
var $encryptIV;
|
171 |
+
|
172 |
+
/**
|
173 |
+
* A "sliding" Initialization Vector
|
174 |
+
*
|
175 |
+
* @see Crypt_Base::enableContinuousBuffer()
|
176 |
+
* @see Crypt_Base::_clearBuffers()
|
177 |
+
* @var string
|
178 |
+
* @access private
|
179 |
+
*/
|
180 |
+
var $decryptIV;
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Continuous Buffer status
|
184 |
+
*
|
185 |
+
* @see Crypt_Base::enableContinuousBuffer()
|
186 |
+
* @var bool
|
187 |
+
* @access private
|
188 |
+
*/
|
189 |
+
var $continuousBuffer = false;
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Encryption buffer for CTR, OFB and CFB modes
|
193 |
+
*
|
194 |
+
* @see Crypt_Base::encrypt()
|
195 |
+
* @see Crypt_Base::_clearBuffers()
|
196 |
+
* @var array
|
197 |
+
* @access private
|
198 |
+
*/
|
199 |
+
var $enbuffer;
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Decryption buffer for CTR, OFB and CFB modes
|
203 |
+
*
|
204 |
+
* @see Crypt_Base::decrypt()
|
205 |
+
* @see Crypt_Base::_clearBuffers()
|
206 |
+
* @var array
|
207 |
+
* @access private
|
208 |
+
*/
|
209 |
+
var $debuffer;
|
210 |
+
|
211 |
+
/**
|
212 |
+
* mcrypt resource for encryption
|
213 |
+
*
|
214 |
+
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
215 |
+
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
216 |
+
*
|
217 |
+
* @see Crypt_Base::encrypt()
|
218 |
+
* @var resource
|
219 |
+
* @access private
|
220 |
+
*/
|
221 |
+
var $enmcrypt;
|
222 |
+
|
223 |
+
/**
|
224 |
+
* mcrypt resource for decryption
|
225 |
+
*
|
226 |
+
* The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
|
227 |
+
* Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
|
228 |
+
*
|
229 |
+
* @see Crypt_Base::decrypt()
|
230 |
+
* @var resource
|
231 |
+
* @access private
|
232 |
+
*/
|
233 |
+
var $demcrypt;
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Does the enmcrypt resource need to be (re)initialized?
|
237 |
+
*
|
238 |
+
* @see Crypt_Twofish::setKey()
|
239 |
+
* @see Crypt_Twofish::setIV()
|
240 |
+
* @var bool
|
241 |
+
* @access private
|
242 |
+
*/
|
243 |
+
var $enchanged = true;
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Does the demcrypt resource need to be (re)initialized?
|
247 |
+
*
|
248 |
+
* @see Crypt_Twofish::setKey()
|
249 |
+
* @see Crypt_Twofish::setIV()
|
250 |
+
* @var bool
|
251 |
+
* @access private
|
252 |
+
*/
|
253 |
+
var $dechanged = true;
|
254 |
+
|
255 |
+
/**
|
256 |
+
* mcrypt resource for CFB mode
|
257 |
+
*
|
258 |
+
* mcrypt's CFB mode, in (and only in) buffered context,
|
259 |
+
* is broken, so phpseclib implements the CFB mode by it self,
|
260 |
+
* even when the mcrypt php extension is available.
|
261 |
+
*
|
262 |
+
* In order to do the CFB-mode work (fast) phpseclib
|
263 |
+
* use a separate ECB-mode mcrypt resource.
|
264 |
+
*
|
265 |
+
* @link http://phpseclib.sourceforge.net/cfb-demo.phps
|
266 |
+
* @see Crypt_Base::encrypt()
|
267 |
+
* @see Crypt_Base::decrypt()
|
268 |
+
* @see Crypt_Base::_setupMcrypt()
|
269 |
+
* @var resource
|
270 |
+
* @access private
|
271 |
+
*/
|
272 |
+
var $ecb;
|
273 |
+
|
274 |
+
/**
|
275 |
+
* Optimizing value while CFB-encrypting
|
276 |
+
*
|
277 |
+
* Only relevant if $continuousBuffer enabled
|
278 |
+
* and $engine == CRYPT_ENGINE_MCRYPT
|
279 |
+
*
|
280 |
+
* It's faster to re-init $enmcrypt if
|
281 |
+
* $buffer bytes > $cfb_init_len than
|
282 |
+
* using the $ecb resource furthermore.
|
283 |
+
*
|
284 |
+
* This value depends of the chosen cipher
|
285 |
+
* and the time it would be needed for it's
|
286 |
+
* initialization [by mcrypt_generic_init()]
|
287 |
+
* which, typically, depends on the complexity
|
288 |
+
* on its internaly Key-expanding algorithm.
|
289 |
+
*
|
290 |
+
* @see Crypt_Base::encrypt()
|
291 |
+
* @var int
|
292 |
+
* @access private
|
293 |
+
*/
|
294 |
+
var $cfb_init_len = 600;
|
295 |
+
|
296 |
+
/**
|
297 |
+
* Does internal cipher state need to be (re)initialized?
|
298 |
+
*
|
299 |
+
* @see setKey()
|
300 |
+
* @see setIV()
|
301 |
+
* @see disableContinuousBuffer()
|
302 |
+
* @var bool
|
303 |
+
* @access private
|
304 |
+
*/
|
305 |
+
var $changed = true;
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Padding status
|
309 |
+
*
|
310 |
+
* @see Crypt_Base::enablePadding()
|
311 |
+
* @var bool
|
312 |
+
* @access private
|
313 |
+
*/
|
314 |
+
var $padding = true;
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Is the mode one that is paddable?
|
318 |
+
*
|
319 |
+
* @see Crypt_Base::Crypt_Base()
|
320 |
+
* @var bool
|
321 |
+
* @access private
|
322 |
+
*/
|
323 |
+
var $paddable = false;
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Holds which crypt engine internaly should be use,
|
327 |
+
* which will be determined automatically on __construct()
|
328 |
+
*
|
329 |
+
* Currently available $engines are:
|
330 |
+
* - CRYPT_ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required)
|
331 |
+
* - CRYPT_ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required)
|
332 |
+
* - CRYPT_ENGINE_INTERNAL (slower, pure php-engine, no php-extension required)
|
333 |
+
*
|
334 |
+
* @see Crypt_Base::_setEngine()
|
335 |
+
* @see Crypt_Base::encrypt()
|
336 |
+
* @see Crypt_Base::decrypt()
|
337 |
+
* @var int
|
338 |
+
* @access private
|
339 |
+
*/
|
340 |
+
var $engine;
|
341 |
+
|
342 |
+
/**
|
343 |
+
* Holds the preferred crypt engine
|
344 |
+
*
|
345 |
+
* @see Crypt_Base::_setEngine()
|
346 |
+
* @see Crypt_Base::setPreferredEngine()
|
347 |
+
* @var int
|
348 |
+
* @access private
|
349 |
+
*/
|
350 |
+
var $preferredEngine;
|
351 |
+
|
352 |
+
/**
|
353 |
+
* The mcrypt specific name of the cipher
|
354 |
+
*
|
355 |
+
* Only used if $engine == CRYPT_ENGINE_MCRYPT
|
356 |
+
*
|
357 |
+
* @link http://www.php.net/mcrypt_module_open
|
358 |
+
* @link http://www.php.net/mcrypt_list_algorithms
|
359 |
+
* @see Crypt_Base::_setupMcrypt()
|
360 |
+
* @var string
|
361 |
+
* @access private
|
362 |
+
*/
|
363 |
+
var $cipher_name_mcrypt;
|
364 |
+
|
365 |
+
/**
|
366 |
+
* The openssl specific name of the cipher
|
367 |
+
*
|
368 |
+
* Only used if $engine == CRYPT_ENGINE_OPENSSL
|
369 |
+
*
|
370 |
+
* @link http://www.php.net/openssl-get-cipher-methods
|
371 |
+
* @var string
|
372 |
+
* @access private
|
373 |
+
*/
|
374 |
+
var $cipher_name_openssl;
|
375 |
+
|
376 |
+
/**
|
377 |
+
* The openssl specific name of the cipher in ECB mode
|
378 |
+
*
|
379 |
+
* If OpenSSL does not support the mode we're trying to use (CTR)
|
380 |
+
* it can still be emulated with ECB mode.
|
381 |
+
*
|
382 |
+
* @link http://www.php.net/openssl-get-cipher-methods
|
383 |
+
* @var string
|
384 |
+
* @access private
|
385 |
+
*/
|
386 |
+
var $cipher_name_openssl_ecb;
|
387 |
+
|
388 |
+
/**
|
389 |
+
* The default salt used by setPassword()
|
390 |
+
*
|
391 |
+
* @see Crypt_Base::setPassword()
|
392 |
+
* @var string
|
393 |
+
* @access private
|
394 |
+
*/
|
395 |
+
var $password_default_salt = 'phpseclib/salt';
|
396 |
+
|
397 |
+
/**
|
398 |
+
* The namespace used by the cipher for its constants.
|
399 |
+
*
|
400 |
+
* ie: AES.php is using CRYPT_AES_MODE_* for its constants
|
401 |
+
* so $const_namespace is AES
|
402 |
+
*
|
403 |
+
* DES.php is using CRYPT_DES_MODE_* for its constants
|
404 |
+
* so $const_namespace is DES... and so on
|
405 |
+
*
|
406 |
+
* All CRYPT_<$const_namespace>_MODE_* are aliases of
|
407 |
+
* the generic CRYPT_MODE_* constants, so both could be used
|
408 |
+
* for each cipher.
|
409 |
+
*
|
410 |
+
* Example:
|
411 |
+
* $aes = new Crypt_AES(CRYPT_AES_MODE_CFB); // $aes will operate in cfb mode
|
412 |
+
* $aes = new Crypt_AES(CRYPT_MODE_CFB); // identical
|
413 |
+
*
|
414 |
+
* @see Crypt_Base::Crypt_Base()
|
415 |
+
* @var string
|
416 |
+
* @access private
|
417 |
+
*/
|
418 |
+
var $const_namespace;
|
419 |
+
|
420 |
+
/**
|
421 |
+
* The name of the performance-optimized callback function
|
422 |
+
*
|
423 |
+
* Used by encrypt() / decrypt()
|
424 |
+
* only if $engine == CRYPT_ENGINE_INTERNAL
|
425 |
+
*
|
426 |
+
* @see Crypt_Base::encrypt()
|
427 |
+
* @see Crypt_Base::decrypt()
|
428 |
+
* @see Crypt_Base::_setupInlineCrypt()
|
429 |
+
* @see Crypt_Base::$use_inline_crypt
|
430 |
+
* @var Callback
|
431 |
+
* @access private
|
432 |
+
*/
|
433 |
+
var $inline_crypt;
|
434 |
+
|
435 |
+
/**
|
436 |
+
* Holds whether performance-optimized $inline_crypt() can/should be used.
|
437 |
+
*
|
438 |
+
* @see Crypt_Base::encrypt()
|
439 |
+
* @see Crypt_Base::decrypt()
|
440 |
+
* @see Crypt_Base::inline_crypt
|
441 |
+
* @var mixed
|
442 |
+
* @access private
|
443 |
+
*/
|
444 |
+
var $use_inline_crypt;
|
445 |
+
|
446 |
+
/**
|
447 |
+
* If OpenSSL can be used in ECB but not in CTR we can emulate CTR
|
448 |
+
*
|
449 |
+
* @see Crypt_Base::_openssl_ctr_process()
|
450 |
+
* @var bool
|
451 |
+
* @access private
|
452 |
+
*/
|
453 |
+
var $openssl_emulate_ctr = false;
|
454 |
+
|
455 |
+
/**
|
456 |
+
* Determines what options are passed to openssl_encrypt/decrypt
|
457 |
+
*
|
458 |
+
* @see Crypt_Base::isValidEngine()
|
459 |
+
* @var mixed
|
460 |
+
* @access private
|
461 |
+
*/
|
462 |
+
var $openssl_options;
|
463 |
+
|
464 |
+
/**
|
465 |
+
* Has the key length explicitly been set or should it be derived from the key, itself?
|
466 |
+
*
|
467 |
+
* @see self::setKeyLength()
|
468 |
+
* @var bool
|
469 |
+
* @access private
|
470 |
+
*/
|
471 |
+
var $explicit_key_length = false;
|
472 |
+
|
473 |
+
/**
|
474 |
+
* Don't truncate / null pad key
|
475 |
+
*
|
476 |
+
* @see self::_clearBuffers()
|
477 |
+
* @var bool
|
478 |
+
* @access private
|
479 |
+
*/
|
480 |
+
var $skip_key_adjustment = false;
|
481 |
+
|
482 |
+
/**
|
483 |
+
* Default Constructor.
|
484 |
+
*
|
485 |
+
* Determines whether or not the mcrypt extension should be used.
|
486 |
+
*
|
487 |
+
* $mode could be:
|
488 |
+
*
|
489 |
+
* - CRYPT_MODE_ECB
|
490 |
+
*
|
491 |
+
* - CRYPT_MODE_CBC
|
492 |
+
*
|
493 |
+
* - CRYPT_MODE_CTR
|
494 |
+
*
|
495 |
+
* - CRYPT_MODE_CFB
|
496 |
+
*
|
497 |
+
* - CRYPT_MODE_OFB
|
498 |
+
*
|
499 |
+
* (or the alias constants of the chosen cipher, for example for AES: CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC ...)
|
500 |
+
*
|
501 |
+
* If not explicitly set, CRYPT_MODE_CBC will be used.
|
502 |
+
*
|
503 |
+
* @param int $mode
|
504 |
+
* @access public
|
505 |
+
*/
|
506 |
+
function Crypt_Base($mode = CRYPT_MODE_CBC)
|
507 |
+
{
|
508 |
+
// $mode dependent settings
|
509 |
+
switch ($mode) {
|
510 |
+
case CRYPT_MODE_ECB:
|
511 |
+
$this->paddable = true;
|
512 |
+
$this->mode = CRYPT_MODE_ECB;
|
513 |
+
break;
|
514 |
+
case CRYPT_MODE_CTR:
|
515 |
+
case CRYPT_MODE_CFB:
|
516 |
+
case CRYPT_MODE_OFB:
|
517 |
+
case CRYPT_MODE_STREAM:
|
518 |
+
$this->mode = $mode;
|
519 |
+
break;
|
520 |
+
case CRYPT_MODE_CBC:
|
521 |
+
default:
|
522 |
+
$this->paddable = true;
|
523 |
+
$this->mode = CRYPT_MODE_CBC;
|
524 |
+
}
|
525 |
+
|
526 |
+
$this->_setEngine();
|
527 |
+
|
528 |
+
// Determining whether inline crypting can be used by the cipher
|
529 |
+
if ($this->use_inline_crypt !== false && function_exists('create_function')) {
|
530 |
+
$this->use_inline_crypt = true;
|
531 |
+
}
|
532 |
+
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Sets the initialization vector. (optional)
|
536 |
+
*
|
537 |
+
* SetIV is not required when CRYPT_MODE_ECB (or ie for AES: CRYPT_AES_MODE_ECB) is being used. If not explicitly set, it'll be assumed
|
538 |
+
* to be all zero's.
|
539 |
+
*
|
540 |
+
* @access public
|
541 |
+
* @param string $iv
|
542 |
+
* @internal Can be overwritten by a sub class, but does not have to be
|
543 |
+
*/
|
544 |
+
function setIV($iv)
|
545 |
+
{
|
546 |
+
if ($this->mode == CRYPT_MODE_ECB) {
|
547 |
+
return;
|
548 |
+
}
|
549 |
+
|
550 |
+
$this->iv = $iv;
|
551 |
+
$this->changed = true;
|
552 |
+
}
|
553 |
+
|
554 |
+
/**
|
555 |
+
* Sets the key length.
|
556 |
+
*
|
557 |
+
* Keys with explicitly set lengths need to be treated accordingly
|
558 |
+
*
|
559 |
+
* @access public
|
560 |
+
* @param int $length
|
561 |
+
*/
|
562 |
+
function setKeyLength($length)
|
563 |
+
{
|
564 |
+
$this->explicit_key_length = true;
|
565 |
+
$this->changed = true;
|
566 |
+
$this->_setEngine();
|
567 |
+
}
|
568 |
+
|
569 |
+
/**
|
570 |
+
* Returns the current key length in bits
|
571 |
+
*
|
572 |
+
* @access public
|
573 |
+
* @return int
|
574 |
+
*/
|
575 |
+
function getKeyLength()
|
576 |
+
{
|
577 |
+
return $this->key_length << 3;
|
578 |
+
}
|
579 |
+
|
580 |
+
/**
|
581 |
+
* Returns the current block length in bits
|
582 |
+
*
|
583 |
+
* @access public
|
584 |
+
* @return int
|
585 |
+
*/
|
586 |
+
function getBlockLength()
|
587 |
+
{
|
588 |
+
return $this->block_size << 3;
|
589 |
+
}
|
590 |
+
|
591 |
+
/**
|
592 |
+
* Sets the key.
|
593 |
+
*
|
594 |
+
* The min/max length(s) of the key depends on the cipher which is used.
|
595 |
+
* If the key not fits the length(s) of the cipher it will paded with null bytes
|
596 |
+
* up to the closest valid key length. If the key is more than max length,
|
597 |
+
* we trim the excess bits.
|
598 |
+
*
|
599 |
+
* If the key is not explicitly set, it'll be assumed to be all null bytes.
|
600 |
+
*
|
601 |
+
* @access public
|
602 |
+
* @param string $key
|
603 |
+
* @internal Could, but not must, extend by the child Crypt_* class
|
604 |
+
*/
|
605 |
+
function setKey($key)
|
606 |
+
{
|
607 |
+
if (!$this->explicit_key_length) {
|
608 |
+
$this->setKeyLength(strlen($key) << 3);
|
609 |
+
$this->explicit_key_length = false;
|
610 |
+
}
|
611 |
+
|
612 |
+
$this->key = $key;
|
613 |
+
$this->changed = true;
|
614 |
+
$this->_setEngine();
|
615 |
+
}
|
616 |
+
|
617 |
+
/**
|
618 |
+
* Sets the password.
|
619 |
+
*
|
620 |
+
* Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
|
621 |
+
* {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1:
|
622 |
+
* $hash, $salt, $count, $dkLen
|
623 |
+
*
|
624 |
+
* Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php
|
625 |
+
*
|
626 |
+
* @see Crypt/Hash.php
|
627 |
+
* @param string $password
|
628 |
+
* @param string $method
|
629 |
+
* @return bool
|
630 |
+
* @access public
|
631 |
+
* @internal Could, but not must, extend by the child Crypt_* class
|
632 |
+
*/
|
633 |
+
function setPassword($password, $method = 'pbkdf2')
|
634 |
+
{
|
635 |
+
$key = '';
|
636 |
+
|
637 |
+
switch ($method) {
|
638 |
+
default: // 'pbkdf2' or 'pbkdf1'
|
639 |
+
$func_args = func_get_args();
|
640 |
+
|
641 |
+
// Hash function
|
642 |
+
$hash = isset($func_args[2]) ? $func_args[2] : 'sha1';
|
643 |
+
|
644 |
+
// WPA and WPA2 use the SSID as the salt
|
645 |
+
$salt = isset($func_args[3]) ? $func_args[3] : $this->password_default_salt;
|
646 |
+
|
647 |
+
// RFC2898#section-4.2 uses 1,000 iterations by default
|
648 |
+
// WPA and WPA2 use 4,096.
|
649 |
+
$count = isset($func_args[4]) ? $func_args[4] : 1000;
|
650 |
+
|
651 |
+
// Keylength
|
652 |
+
if (isset($func_args[5])) {
|
653 |
+
$dkLen = $func_args[5];
|
654 |
+
} else {
|
655 |
+
$dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
|
656 |
+
}
|
657 |
+
|
658 |
+
switch (true) {
|
659 |
+
case $method == 'pbkdf1':
|
660 |
+
if (!class_exists('Crypt_Hash')) {
|
661 |
+
include_once 'Crypt/Hash.php';
|
662 |
+
}
|
663 |
+
$hashObj = new Crypt_Hash();
|
664 |
+
$hashObj->setHash($hash);
|
665 |
+
if ($dkLen > $hashObj->getLength()) {
|
666 |
+
user_error('Derived key too long');
|
667 |
+
return false;
|
668 |
+
}
|
669 |
+
$t = $password . $salt;
|
670 |
+
for ($i = 0; $i < $count; ++$i) {
|
671 |
+
$t = $hashObj->hash($t);
|
672 |
+
}
|
673 |
+
$key = substr($t, 0, $dkLen);
|
674 |
+
|
675 |
+
$this->setKey(substr($key, 0, $dkLen >> 1));
|
676 |
+
$this->setIV(substr($key, $dkLen >> 1));
|
677 |
+
|
678 |
+
return true;
|
679 |
+
// Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable
|
680 |
+
case !function_exists('hash_pbkdf2'):
|
681 |
+
case !function_exists('hash_algos'):
|
682 |
+
case !in_array($hash, hash_algos()):
|
683 |
+
if (!class_exists('Crypt_Hash')) {
|
684 |
+
include_once 'Crypt/Hash.php';
|
685 |
+
}
|
686 |
+
$i = 1;
|
687 |
+
while (strlen($key) < $dkLen) {
|
688 |
+
$hmac = new Crypt_Hash();
|
689 |
+
$hmac->setHash($hash);
|
690 |
+
$hmac->setKey($password);
|
691 |
+
$f = $u = $hmac->hash($salt . pack('N', $i++));
|
692 |
+
for ($j = 2; $j <= $count; ++$j) {
|
693 |
+
$u = $hmac->hash($u);
|
694 |
+
$f^= $u;
|
695 |
+
}
|
696 |
+
$key.= $f;
|
697 |
+
}
|
698 |
+
$key = substr($key, 0, $dkLen);
|
699 |
+
break;
|
700 |
+
default:
|
701 |
+
$key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true);
|
702 |
+
}
|
703 |
+
}
|
704 |
+
|
705 |
+
$this->setKey($key);
|
706 |
+
|
707 |
+
return true;
|
708 |
+
}
|
709 |
+
|
710 |
+
/**
|
711 |
+
* Encrypts a message.
|
712 |
+
*
|
713 |
+
* $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher
|
714 |
+
* implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's
|
715 |
+
* necessary are discussed in the following
|
716 |
+
* URL:
|
717 |
+
*
|
718 |
+
* {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
|
719 |
+
*
|
720 |
+
* An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
|
721 |
+
* strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that
|
722 |
+
* length.
|
723 |
+
*
|
724 |
+
* @see Crypt_Base::decrypt()
|
725 |
+
* @access public
|
726 |
+
* @param string $plaintext
|
727 |
+
* @return string $ciphertext
|
728 |
+
* @internal Could, but not must, extend by the child Crypt_* class
|
729 |
+
*/
|
730 |
+
function encrypt($plaintext)
|
731 |
+
{
|
732 |
+
if ($this->paddable) {
|
733 |
+
$plaintext = $this->_pad($plaintext);
|
734 |
+
}
|
735 |
+
|
736 |
+
if ($this->engine === CRYPT_ENGINE_OPENSSL) {
|
737 |
+
if ($this->changed) {
|
738 |
+
$this->_clearBuffers();
|
739 |
+
$this->changed = false;
|
740 |
+
}
|
741 |
+
switch ($this->mode) {
|
742 |
+
case CRYPT_MODE_STREAM:
|
743 |
+
return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
744 |
+
case CRYPT_MODE_ECB:
|
745 |
+
$result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
746 |
+
return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
|
747 |
+
case CRYPT_MODE_CBC:
|
748 |
+
$result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
|
749 |
+
if ($this->continuousBuffer) {
|
750 |
+
$this->encryptIV = substr($result, -$this->block_size);
|
751 |
+
}
|
752 |
+
return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
|
753 |
+
case CRYPT_MODE_CTR:
|
754 |
+
return $this->_openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer);
|
755 |
+
case CRYPT_MODE_CFB:
|
756 |
+
// cfb loosely routines inspired by openssl's:
|
757 |
+
// {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
|
758 |
+
$ciphertext = '';
|
759 |
+
if ($this->continuousBuffer) {
|
760 |
+
$iv = &$this->encryptIV;
|
761 |
+
$pos = &$this->enbuffer['pos'];
|
762 |
+
} else {
|
763 |
+
$iv = $this->encryptIV;
|
764 |
+
$pos = 0;
|
765 |
+
}
|
766 |
+
$len = strlen($plaintext);
|
767 |
+
$i = 0;
|
768 |
+
if ($pos) {
|
769 |
+
$orig_pos = $pos;
|
770 |
+
$max = $this->block_size - $pos;
|
771 |
+
if ($len >= $max) {
|
772 |
+
$i = $max;
|
773 |
+
$len-= $max;
|
774 |
+
$pos = 0;
|
775 |
+
} else {
|
776 |
+
$i = $len;
|
777 |
+
$pos+= $len;
|
778 |
+
$len = 0;
|
779 |
+
}
|
780 |
+
// ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
|
781 |
+
$ciphertext = substr($iv, $orig_pos) ^ $plaintext;
|
782 |
+
$iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
|
783 |
+
$plaintext = substr($plaintext, $i);
|
784 |
+
}
|
785 |
+
|
786 |
+
$overflow = $len % $this->block_size;
|
787 |
+
|
788 |
+
if ($overflow) {
|
789 |
+
$ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
|
790 |
+
$iv = $this->_string_pop($ciphertext, $this->block_size);
|
791 |
+
|
792 |
+
$size = $len - $overflow;
|
793 |
+
$block = $iv ^ substr($plaintext, -$overflow);
|
794 |
+
$iv = substr_replace($iv, $block, 0, $overflow);
|
795 |
+
$ciphertext.= $block;
|
796 |
+
$pos = $overflow;
|
797 |
+
} elseif ($len) {
|
798 |
+
$ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
|
799 |
+
$iv = substr($ciphertext, -$this->block_size);
|
800 |
+
}
|
801 |
+
|
802 |
+
return $ciphertext;
|
803 |
+
case CRYPT_MODE_OFB:
|
804 |
+
return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
|
805 |
+
}
|
806 |
+
}
|
807 |
+
|
808 |
+
if ($this->engine === CRYPT_ENGINE_MCRYPT) {
|
809 |
+
if ($this->changed) {
|
810 |
+
$this->_setupMcrypt();
|
811 |
+
$this->changed = false;
|
812 |
+
}
|
813 |
+
if ($this->enchanged) {
|
814 |
+
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
815 |
+
$this->enchanged = false;
|
816 |
+
}
|
817 |
+
|
818 |
+
// re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
|
819 |
+
// using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
|
820 |
+
// rewritten CFB implementation the above outputs the same thing twice.
|
821 |
+
if ($this->mode == CRYPT_MODE_CFB && $this->continuousBuffer) {
|
822 |
+
$block_size = $this->block_size;
|
823 |
+
$iv = &$this->encryptIV;
|
824 |
+
$pos = &$this->enbuffer['pos'];
|
825 |
+
$len = strlen($plaintext);
|
826 |
+
$ciphertext = '';
|
827 |
+
$i = 0;
|
828 |
+
if ($pos) {
|
829 |
+
$orig_pos = $pos;
|
830 |
+
$max = $block_size - $pos;
|
831 |
+
if ($len >= $max) {
|
832 |
+
$i = $max;
|
833 |
+
$len-= $max;
|
834 |
+
$pos = 0;
|
835 |
+
} else {
|
836 |
+
$i = $len;
|
837 |
+
$pos+= $len;
|
838 |
+
$len = 0;
|
839 |
+
}
|
840 |
+
$ciphertext = substr($iv, $orig_pos) ^ $plaintext;
|
841 |
+
$iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
|
842 |
+
$this->enbuffer['enmcrypt_init'] = true;
|
843 |
+
}
|
844 |
+
if ($len >= $block_size) {
|
845 |
+
if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) {
|
846 |
+
if ($this->enbuffer['enmcrypt_init'] === true) {
|
847 |
+
mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
|
848 |
+
$this->enbuffer['enmcrypt_init'] = false;
|
849 |
+
}
|
850 |
+
$ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
|
851 |
+
$iv = substr($ciphertext, -$block_size);
|
852 |
+
$len%= $block_size;
|
853 |
+
} else {
|
854 |
+
while ($len >= $block_size) {
|
855 |
+
$iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
|
856 |
+
$ciphertext.= $iv;
|
857 |
+
$len-= $block_size;
|
858 |
+
$i+= $block_size;
|
859 |
+
}
|
860 |
+
}
|
861 |
+
}
|
862 |
+
|
863 |
+
if ($len) {
|
864 |
+
$iv = mcrypt_generic($this->ecb, $iv);
|
865 |
+
$block = $iv ^ substr($plaintext, -$len);
|
866 |
+
$iv = substr_replace($iv, $block, 0, $len);
|
867 |
+
$ciphertext.= $block;
|
868 |
+
$pos = $len;
|
869 |
+
}
|
870 |
+
|
871 |
+
return $ciphertext;
|
872 |
+
}
|
873 |
+
|
874 |
+
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
|
875 |
+
|
876 |
+
if (!$this->continuousBuffer) {
|
877 |
+
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
|
878 |
+
}
|
879 |
+
|
880 |
+
return $ciphertext;
|
881 |
+
}
|
882 |
+
|
883 |
+
if ($this->changed) {
|
884 |
+
$this->_setup();
|
885 |
+
$this->changed = false;
|
886 |
+
}
|
887 |
+
if ($this->use_inline_crypt) {
|
888 |
+
$inline = $this->inline_crypt;
|
889 |
+
return $inline('encrypt', $this, $plaintext);
|
890 |
+
}
|
891 |
+
|
892 |
+
$buffer = &$this->enbuffer;
|
893 |
+
$block_size = $this->block_size;
|
894 |
+
$ciphertext = '';
|
895 |
+
switch ($this->mode) {
|
896 |
+
case CRYPT_MODE_ECB:
|
897 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
898 |
+
$ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));
|
899 |
+
}
|
900 |
+
break;
|
901 |
+
case CRYPT_MODE_CBC:
|
902 |
+
$xor = $this->encryptIV;
|
903 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
904 |
+
$block = substr($plaintext, $i, $block_size);
|
905 |
+
$block = $this->_encryptBlock($block ^ $xor);
|
906 |
+
$xor = $block;
|
907 |
+
$ciphertext.= $block;
|
908 |
+
}
|
909 |
+
if ($this->continuousBuffer) {
|
910 |
+
$this->encryptIV = $xor;
|
911 |
+
}
|
912 |
+
break;
|
913 |
+
case CRYPT_MODE_CTR:
|
914 |
+
$xor = $this->encryptIV;
|
915 |
+
if (strlen($buffer['ciphertext'])) {
|
916 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
917 |
+
$block = substr($plaintext, $i, $block_size);
|
918 |
+
if (strlen($block) > strlen($buffer['ciphertext'])) {
|
919 |
+
$buffer['ciphertext'].= $this->_encryptBlock($xor);
|
920 |
+
}
|
921 |
+
$this->_increment_str($xor);
|
922 |
+
$key = $this->_string_shift($buffer['ciphertext'], $block_size);
|
923 |
+
$ciphertext.= $block ^ $key;
|
924 |
+
}
|
925 |
+
} else {
|
926 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
927 |
+
$block = substr($plaintext, $i, $block_size);
|
928 |
+
$key = $this->_encryptBlock($xor);
|
929 |
+
$this->_increment_str($xor);
|
930 |
+
$ciphertext.= $block ^ $key;
|
931 |
+
}
|
932 |
+
}
|
933 |
+
if ($this->continuousBuffer) {
|
934 |
+
$this->encryptIV = $xor;
|
935 |
+
if ($start = strlen($plaintext) % $block_size) {
|
936 |
+
$buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
|
937 |
+
}
|
938 |
+
}
|
939 |
+
break;
|
940 |
+
case CRYPT_MODE_CFB:
|
941 |
+
// cfb loosely routines inspired by openssl's:
|
942 |
+
// {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
|
943 |
+
if ($this->continuousBuffer) {
|
944 |
+
$iv = &$this->encryptIV;
|
945 |
+
$pos = &$buffer['pos'];
|
946 |
+
} else {
|
947 |
+
$iv = $this->encryptIV;
|
948 |
+
$pos = 0;
|
949 |
+
}
|
950 |
+
$len = strlen($plaintext);
|
951 |
+
$i = 0;
|
952 |
+
if ($pos) {
|
953 |
+
$orig_pos = $pos;
|
954 |
+
$max = $block_size - $pos;
|
955 |
+
if ($len >= $max) {
|
956 |
+
$i = $max;
|
957 |
+
$len-= $max;
|
958 |
+
$pos = 0;
|
959 |
+
} else {
|
960 |
+
$i = $len;
|
961 |
+
$pos+= $len;
|
962 |
+
$len = 0;
|
963 |
+
}
|
964 |
+
// ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
|
965 |
+
$ciphertext = substr($iv, $orig_pos) ^ $plaintext;
|
966 |
+
$iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
|
967 |
+
}
|
968 |
+
while ($len >= $block_size) {
|
969 |
+
$iv = $this->_encryptBlock($iv) ^ substr($plaintext, $i, $block_size);
|
970 |
+
$ciphertext.= $iv;
|
971 |
+
$len-= $block_size;
|
972 |
+
$i+= $block_size;
|
973 |
+
}
|
974 |
+
if ($len) {
|
975 |
+
$iv = $this->_encryptBlock($iv);
|
976 |
+
$block = $iv ^ substr($plaintext, $i);
|
977 |
+
$iv = substr_replace($iv, $block, 0, $len);
|
978 |
+
$ciphertext.= $block;
|
979 |
+
$pos = $len;
|
980 |
+
}
|
981 |
+
break;
|
982 |
+
case CRYPT_MODE_OFB:
|
983 |
+
$xor = $this->encryptIV;
|
984 |
+
if (strlen($buffer['xor'])) {
|
985 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
986 |
+
$block = substr($plaintext, $i, $block_size);
|
987 |
+
if (strlen($block) > strlen($buffer['xor'])) {
|
988 |
+
$xor = $this->_encryptBlock($xor);
|
989 |
+
$buffer['xor'].= $xor;
|
990 |
+
}
|
991 |
+
$key = $this->_string_shift($buffer['xor'], $block_size);
|
992 |
+
$ciphertext.= $block ^ $key;
|
993 |
+
}
|
994 |
+
} else {
|
995 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
996 |
+
$xor = $this->_encryptBlock($xor);
|
997 |
+
$ciphertext.= substr($plaintext, $i, $block_size) ^ $xor;
|
998 |
+
}
|
999 |
+
$key = $xor;
|
1000 |
+
}
|
1001 |
+
if ($this->continuousBuffer) {
|
1002 |
+
$this->encryptIV = $xor;
|
1003 |
+
if ($start = strlen($plaintext) % $block_size) {
|
1004 |
+
$buffer['xor'] = substr($key, $start) . $buffer['xor'];
|
1005 |
+
}
|
1006 |
+
}
|
1007 |
+
break;
|
1008 |
+
case CRYPT_MODE_STREAM:
|
1009 |
+
$ciphertext = $this->_encryptBlock($plaintext);
|
1010 |
+
break;
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
return $ciphertext;
|
1014 |
+
}
|
1015 |
+
|
1016 |
+
/**
|
1017 |
+
* Decrypts a message.
|
1018 |
+
*
|
1019 |
+
* If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until
|
1020 |
+
* it is.
|
1021 |
+
*
|
1022 |
+
* @see Crypt_Base::encrypt()
|
1023 |
+
* @access public
|
1024 |
+
* @param string $ciphertext
|
1025 |
+
* @return string $plaintext
|
1026 |
+
* @internal Could, but not must, extend by the child Crypt_* class
|
1027 |
+
*/
|
1028 |
+
function decrypt($ciphertext)
|
1029 |
+
{
|
1030 |
+
if ($this->paddable) {
|
1031 |
+
// we pad with chr(0) since that's what mcrypt_generic does. to quote from {@link http://www.php.net/function.mcrypt-generic}:
|
1032 |
+
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
|
1033 |
+
$ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
|
1034 |
+
}
|
1035 |
+
|
1036 |
+
if ($this->engine === CRYPT_ENGINE_OPENSSL) {
|
1037 |
+
if ($this->changed) {
|
1038 |
+
$this->_clearBuffers();
|
1039 |
+
$this->changed = false;
|
1040 |
+
}
|
1041 |
+
switch ($this->mode) {
|
1042 |
+
case CRYPT_MODE_STREAM:
|
1043 |
+
$plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
1044 |
+
break;
|
1045 |
+
case CRYPT_MODE_ECB:
|
1046 |
+
if (!defined('OPENSSL_RAW_DATA')) {
|
1047 |
+
$ciphertext.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
|
1048 |
+
}
|
1049 |
+
$plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
1050 |
+
break;
|
1051 |
+
case CRYPT_MODE_CBC:
|
1052 |
+
if (!defined('OPENSSL_RAW_DATA')) {
|
1053 |
+
$padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
|
1054 |
+
$ciphertext.= substr(openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
|
1055 |
+
}
|
1056 |
+
$plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV);
|
1057 |
+
if ($this->continuousBuffer) {
|
1058 |
+
$this->decryptIV = substr($ciphertext, -$this->block_size);
|
1059 |
+
}
|
1060 |
+
break;
|
1061 |
+
case CRYPT_MODE_CTR:
|
1062 |
+
$plaintext = $this->_openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer);
|
1063 |
+
break;
|
1064 |
+
case CRYPT_MODE_CFB:
|
1065 |
+
// cfb loosely routines inspired by openssl's:
|
1066 |
+
// {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
|
1067 |
+
$plaintext = '';
|
1068 |
+
if ($this->continuousBuffer) {
|
1069 |
+
$iv = &$this->decryptIV;
|
1070 |
+
$pos = &$this->buffer['pos'];
|
1071 |
+
} else {
|
1072 |
+
$iv = $this->decryptIV;
|
1073 |
+
$pos = 0;
|
1074 |
+
}
|
1075 |
+
$len = strlen($ciphertext);
|
1076 |
+
$i = 0;
|
1077 |
+
if ($pos) {
|
1078 |
+
$orig_pos = $pos;
|
1079 |
+
$max = $this->block_size - $pos;
|
1080 |
+
if ($len >= $max) {
|
1081 |
+
$i = $max;
|
1082 |
+
$len-= $max;
|
1083 |
+
$pos = 0;
|
1084 |
+
} else {
|
1085 |
+
$i = $len;
|
1086 |
+
$pos+= $len;
|
1087 |
+
$len = 0;
|
1088 |
+
}
|
1089 |
+
// ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize
|
1090 |
+
$plaintext = substr($iv, $orig_pos) ^ $ciphertext;
|
1091 |
+
$iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
|
1092 |
+
$ciphertext = substr($ciphertext, $i);
|
1093 |
+
}
|
1094 |
+
$overflow = $len % $this->block_size;
|
1095 |
+
if ($overflow) {
|
1096 |
+
$plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
|
1097 |
+
if ($len - $overflow) {
|
1098 |
+
$iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow);
|
1099 |
+
}
|
1100 |
+
$iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
|
1101 |
+
$plaintext.= $iv ^ substr($ciphertext, -$overflow);
|
1102 |
+
$iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow);
|
1103 |
+
$pos = $overflow;
|
1104 |
+
} elseif ($len) {
|
1105 |
+
$plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
|
1106 |
+
$iv = substr($ciphertext, -$this->block_size);
|
1107 |
+
}
|
1108 |
+
break;
|
1109 |
+
case CRYPT_MODE_OFB:
|
1110 |
+
$plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
|
1111 |
+
}
|
1112 |
+
|
1113 |
+
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
1114 |
+
}
|
1115 |
+
|
1116 |
+
if ($this->engine === CRYPT_ENGINE_MCRYPT) {
|
1117 |
+
$block_size = $this->block_size;
|
1118 |
+
if ($this->changed) {
|
1119 |
+
$this->_setupMcrypt();
|
1120 |
+
$this->changed = false;
|
1121 |
+
}
|
1122 |
+
if ($this->dechanged) {
|
1123 |
+
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
1124 |
+
$this->dechanged = false;
|
1125 |
+
}
|
1126 |
+
|
1127 |
+
if ($this->mode == CRYPT_MODE_CFB && $this->continuousBuffer) {
|
1128 |
+
$iv = &$this->decryptIV;
|
1129 |
+
$pos = &$this->debuffer['pos'];
|
1130 |
+
$len = strlen($ciphertext);
|
1131 |
+
$plaintext = '';
|
1132 |
+
$i = 0;
|
1133 |
+
if ($pos) {
|
1134 |
+
$orig_pos = $pos;
|
1135 |
+
$max = $block_size - $pos;
|
1136 |
+
if ($len >= $max) {
|
1137 |
+
$i = $max;
|
1138 |
+
$len-= $max;
|
1139 |
+
$pos = 0;
|
1140 |
+
} else {
|
1141 |
+
$i = $len;
|
1142 |
+
$pos+= $len;
|
1143 |
+
$len = 0;
|
1144 |
+
}
|
1145 |
+
// ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
|
1146 |
+
$plaintext = substr($iv, $orig_pos) ^ $ciphertext;
|
1147 |
+
$iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
|
1148 |
+
}
|
1149 |
+
if ($len >= $block_size) {
|
1150 |
+
$cb = substr($ciphertext, $i, $len - $len % $block_size);
|
1151 |
+
$plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
|
1152 |
+
$iv = substr($cb, -$block_size);
|
1153 |
+
$len%= $block_size;
|
1154 |
+
}
|
1155 |
+
if ($len) {
|
1156 |
+
$iv = mcrypt_generic($this->ecb, $iv);
|
1157 |
+
$plaintext.= $iv ^ substr($ciphertext, -$len);
|
1158 |
+
$iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
|
1159 |
+
$pos = $len;
|
1160 |
+
}
|
1161 |
+
|
1162 |
+
return $plaintext;
|
1163 |
+
}
|
1164 |
+
|
1165 |
+
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
|
1166 |
+
|
1167 |
+
if (!$this->continuousBuffer) {
|
1168 |
+
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
|
1169 |
+
}
|
1170 |
+
|
1171 |
+
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
1172 |
+
}
|
1173 |
+
|
1174 |
+
if ($this->changed) {
|
1175 |
+
$this->_setup();
|
1176 |
+
$this->changed = false;
|
1177 |
+
}
|
1178 |
+
if ($this->use_inline_crypt) {
|
1179 |
+
$inline = $this->inline_crypt;
|
1180 |
+
return $inline('decrypt', $this, $ciphertext);
|
1181 |
+
}
|
1182 |
+
|
1183 |
+
$block_size = $this->block_size;
|
1184 |
+
|
1185 |
+
$buffer = &$this->debuffer;
|
1186 |
+
$plaintext = '';
|
1187 |
+
switch ($this->mode) {
|
1188 |
+
case CRYPT_MODE_ECB:
|
1189 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
1190 |
+
$plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));
|
1191 |
+
}
|
1192 |
+
break;
|
1193 |
+
case CRYPT_MODE_CBC:
|
1194 |
+
$xor = $this->decryptIV;
|
1195 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
1196 |
+
$block = substr($ciphertext, $i, $block_size);
|
1197 |
+
$plaintext.= $this->_decryptBlock($block) ^ $xor;
|
1198 |
+
$xor = $block;
|
1199 |
+
}
|
1200 |
+
if ($this->continuousBuffer) {
|
1201 |
+
$this->decryptIV = $xor;
|
1202 |
+
}
|
1203 |
+
break;
|
1204 |
+
case CRYPT_MODE_CTR:
|
1205 |
+
$xor = $this->decryptIV;
|
1206 |
+
if (strlen($buffer['ciphertext'])) {
|
1207 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
1208 |
+
$block = substr($ciphertext, $i, $block_size);
|
1209 |
+
if (strlen($block) > strlen($buffer['ciphertext'])) {
|
1210 |
+
$buffer['ciphertext'].= $this->_encryptBlock($xor);
|
1211 |
+
$this->_increment_str($xor);
|
1212 |
+
}
|
1213 |
+
$key = $this->_string_shift($buffer['ciphertext'], $block_size);
|
1214 |
+
$plaintext.= $block ^ $key;
|
1215 |
+
}
|
1216 |
+
} else {
|
1217 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
1218 |
+
$block = substr($ciphertext, $i, $block_size);
|
1219 |
+
$key = $this->_encryptBlock($xor);
|
1220 |
+
$this->_increment_str($xor);
|
1221 |
+
$plaintext.= $block ^ $key;
|
1222 |
+
}
|
1223 |
+
}
|
1224 |
+
if ($this->continuousBuffer) {
|
1225 |
+
$this->decryptIV = $xor;
|
1226 |
+
if ($start = strlen($ciphertext) % $block_size) {
|
1227 |
+
$buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
|
1228 |
+
}
|
1229 |
+
}
|
1230 |
+
break;
|
1231 |
+
case CRYPT_MODE_CFB:
|
1232 |
+
if ($this->continuousBuffer) {
|
1233 |
+
$iv = &$this->decryptIV;
|
1234 |
+
$pos = &$buffer['pos'];
|
1235 |
+
} else {
|
1236 |
+
$iv = $this->decryptIV;
|
1237 |
+
$pos = 0;
|
1238 |
+
}
|
1239 |
+
$len = strlen($ciphertext);
|
1240 |
+
$i = 0;
|
1241 |
+
if ($pos) {
|
1242 |
+
$orig_pos = $pos;
|
1243 |
+
$max = $block_size - $pos;
|
1244 |
+
if ($len >= $max) {
|
1245 |
+
$i = $max;
|
1246 |
+
$len-= $max;
|
1247 |
+
$pos = 0;
|
1248 |
+
} else {
|
1249 |
+
$i = $len;
|
1250 |
+
$pos+= $len;
|
1251 |
+
$len = 0;
|
1252 |
+
}
|
1253 |
+
// ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
|
1254 |
+
$plaintext = substr($iv, $orig_pos) ^ $ciphertext;
|
1255 |
+
$iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
|
1256 |
+
}
|
1257 |
+
while ($len >= $block_size) {
|
1258 |
+
$iv = $this->_encryptBlock($iv);
|
1259 |
+
$cb = substr($ciphertext, $i, $block_size);
|
1260 |
+
$plaintext.= $iv ^ $cb;
|
1261 |
+
$iv = $cb;
|
1262 |
+
$len-= $block_size;
|
1263 |
+
$i+= $block_size;
|
1264 |
+
}
|
1265 |
+
if ($len) {
|
1266 |
+
$iv = $this->_encryptBlock($iv);
|
1267 |
+
$plaintext.= $iv ^ substr($ciphertext, $i);
|
1268 |
+
$iv = substr_replace($iv, substr($ciphertext, $i), 0, $len);
|
1269 |
+
$pos = $len;
|
1270 |
+
}
|
1271 |
+
break;
|
1272 |
+
case CRYPT_MODE_OFB:
|
1273 |
+
$xor = $this->decryptIV;
|
1274 |
+
if (strlen($buffer['xor'])) {
|
1275 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
1276 |
+
$block = substr($ciphertext, $i, $block_size);
|
1277 |
+
if (strlen($block) > strlen($buffer['xor'])) {
|
1278 |
+
$xor = $this->_encryptBlock($xor);
|
1279 |
+
$buffer['xor'].= $xor;
|
1280 |
+
}
|
1281 |
+
$key = $this->_string_shift($buffer['xor'], $block_size);
|
1282 |
+
$plaintext.= $block ^ $key;
|
1283 |
+
}
|
1284 |
+
} else {
|
1285 |
+
for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
|
1286 |
+
$xor = $this->_encryptBlock($xor);
|
1287 |
+
$plaintext.= substr($ciphertext, $i, $block_size) ^ $xor;
|
1288 |
+
}
|
1289 |
+
$key = $xor;
|
1290 |
+
}
|
1291 |
+
if ($this->continuousBuffer) {
|
1292 |
+
$this->decryptIV = $xor;
|
1293 |
+
if ($start = strlen($ciphertext) % $block_size) {
|
1294 |
+
$buffer['xor'] = substr($key, $start) . $buffer['xor'];
|
1295 |
+
}
|
1296 |
+
}
|
1297 |
+
break;
|
1298 |
+
case CRYPT_MODE_STREAM:
|
1299 |
+
$plaintext = $this->_decryptBlock($ciphertext);
|
1300 |
+
break;
|
1301 |
+
}
|
1302 |
+
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
|
1303 |
+
}
|
1304 |
+
|
1305 |
+
/**
|
1306 |
+
* OpenSSL CTR Processor
|
1307 |
+
*
|
1308 |
+
* PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
|
1309 |
+
* for CTR is the same for both encrypting and decrypting this function is re-used by both Crypt_Base::encrypt()
|
1310 |
+
* and Crypt_Base::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this
|
1311 |
+
* function will emulate CTR with ECB when necesary.
|
1312 |
+
*
|
1313 |
+
* @see Crypt_Base::encrypt()
|
1314 |
+
* @see Crypt_Base::decrypt()
|
1315 |
+
* @param string $plaintext
|
1316 |
+
* @param string $encryptIV
|
1317 |
+
* @param array $buffer
|
1318 |
+
* @return string
|
1319 |
+
* @access private
|
1320 |
+
*/
|
1321 |
+
function _openssl_ctr_process($plaintext, &$encryptIV, &$buffer)
|
1322 |
+
{
|
1323 |
+
$ciphertext = '';
|
1324 |
+
|
1325 |
+
$block_size = $this->block_size;
|
1326 |
+
$key = $this->key;
|
1327 |
+
|
1328 |
+
if ($this->openssl_emulate_ctr) {
|
1329 |
+
$xor = $encryptIV;
|
1330 |
+
if (strlen($buffer['ciphertext'])) {
|
1331 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
1332 |
+
$block = substr($plaintext, $i, $block_size);
|
1333 |
+
if (strlen($block) > strlen($buffer['ciphertext'])) {
|
1334 |
+
$result = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1335 |
+
$result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
|
1336 |
+
$buffer['ciphertext'].= $result;
|
1337 |
+
}
|
1338 |
+
$this->_increment_str($xor);
|
1339 |
+
$otp = $this->_string_shift($buffer['ciphertext'], $block_size);
|
1340 |
+
$ciphertext.= $block ^ $otp;
|
1341 |
+
}
|
1342 |
+
} else {
|
1343 |
+
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
1344 |
+
$block = substr($plaintext, $i, $block_size);
|
1345 |
+
$otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1346 |
+
$otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
|
1347 |
+
$this->_increment_str($xor);
|
1348 |
+
$ciphertext.= $block ^ $otp;
|
1349 |
+
}
|
1350 |
+
}
|
1351 |
+
if ($this->continuousBuffer) {
|
1352 |
+
$encryptIV = $xor;
|
1353 |
+
if ($start = strlen($plaintext) % $block_size) {
|
1354 |
+
$buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
|
1355 |
+
}
|
1356 |
+
}
|
1357 |
+
|
1358 |
+
return $ciphertext;
|
1359 |
+
}
|
1360 |
+
|
1361 |
+
if (strlen($buffer['ciphertext'])) {
|
1362 |
+
$ciphertext = $plaintext ^ $this->_string_shift($buffer['ciphertext'], strlen($plaintext));
|
1363 |
+
$plaintext = substr($plaintext, strlen($ciphertext));
|
1364 |
+
|
1365 |
+
if (!strlen($plaintext)) {
|
1366 |
+
return $ciphertext;
|
1367 |
+
}
|
1368 |
+
}
|
1369 |
+
|
1370 |
+
$overflow = strlen($plaintext) % $block_size;
|
1371 |
+
if ($overflow) {
|
1372 |
+
$plaintext2 = $this->_string_pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2
|
1373 |
+
$encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
|
1374 |
+
$temp = $this->_string_pop($encrypted, $block_size);
|
1375 |
+
$ciphertext.= $encrypted . ($plaintext2 ^ $temp);
|
1376 |
+
if ($this->continuousBuffer) {
|
1377 |
+
$buffer['ciphertext'] = substr($temp, $overflow);
|
1378 |
+
$encryptIV = $temp;
|
1379 |
+
}
|
1380 |
+
} elseif (!strlen($buffer['ciphertext'])) {
|
1381 |
+
$ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
|
1382 |
+
$temp = $this->_string_pop($ciphertext, $block_size);
|
1383 |
+
if ($this->continuousBuffer) {
|
1384 |
+
$encryptIV = $temp;
|
1385 |
+
}
|
1386 |
+
}
|
1387 |
+
if ($this->continuousBuffer) {
|
1388 |
+
if (!defined('OPENSSL_RAW_DATA')) {
|
1389 |
+
$encryptIV.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1390 |
+
}
|
1391 |
+
$encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
1392 |
+
if ($overflow) {
|
1393 |
+
$this->_increment_str($encryptIV);
|
1394 |
+
}
|
1395 |
+
}
|
1396 |
+
|
1397 |
+
return $ciphertext;
|
1398 |
+
}
|
1399 |
+
|
1400 |
+
/**
|
1401 |
+
* OpenSSL OFB Processor
|
1402 |
+
*
|
1403 |
+
* PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
|
1404 |
+
* for OFB is the same for both encrypting and decrypting this function is re-used by both Crypt_Base::encrypt()
|
1405 |
+
* and Crypt_Base::decrypt().
|
1406 |
+
*
|
1407 |
+
* @see Crypt_Base::encrypt()
|
1408 |
+
* @see Crypt_Base::decrypt()
|
1409 |
+
* @param string $plaintext
|
1410 |
+
* @param string $encryptIV
|
1411 |
+
* @param array $buffer
|
1412 |
+
* @return string
|
1413 |
+
* @access private
|
1414 |
+
*/
|
1415 |
+
function _openssl_ofb_process($plaintext, &$encryptIV, &$buffer)
|
1416 |
+
{
|
1417 |
+
if (strlen($buffer['xor'])) {
|
1418 |
+
$ciphertext = $plaintext ^ $buffer['xor'];
|
1419 |
+
$buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
|
1420 |
+
$plaintext = substr($plaintext, strlen($ciphertext));
|
1421 |
+
} else {
|
1422 |
+
$ciphertext = '';
|
1423 |
+
}
|
1424 |
+
|
1425 |
+
$block_size = $this->block_size;
|
1426 |
+
|
1427 |
+
$len = strlen($plaintext);
|
1428 |
+
$key = $this->key;
|
1429 |
+
$overflow = $len % $block_size;
|
1430 |
+
|
1431 |
+
if (strlen($plaintext)) {
|
1432 |
+
if ($overflow) {
|
1433 |
+
$ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
|
1434 |
+
$xor = $this->_string_pop($ciphertext, $block_size);
|
1435 |
+
if ($this->continuousBuffer) {
|
1436 |
+
$encryptIV = $xor;
|
1437 |
+
}
|
1438 |
+
$ciphertext.= $this->_string_shift($xor, $overflow) ^ substr($plaintext, -$overflow);
|
1439 |
+
if ($this->continuousBuffer) {
|
1440 |
+
$buffer['xor'] = $xor;
|
1441 |
+
}
|
1442 |
+
} else {
|
1443 |
+
$ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
|
1444 |
+
if ($this->continuousBuffer) {
|
1445 |
+
$encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size);
|
1446 |
+
}
|
1447 |
+
}
|
1448 |
+
}
|
1449 |
+
|
1450 |
+
return $ciphertext;
|
1451 |
+
}
|
1452 |
+
|
1453 |
+
/**
|
1454 |
+
* phpseclib <-> OpenSSL Mode Mapper
|
1455 |
+
*
|
1456 |
+
* May need to be overwritten by classes extending this one in some cases
|
1457 |
+
*
|
1458 |
+
* @return int
|
1459 |
+
* @access private
|
1460 |
+
*/
|
1461 |
+
function _openssl_translate_mode()
|
1462 |
+
{
|
1463 |
+
switch ($this->mode) {
|
1464 |
+
case CRYPT_MODE_ECB:
|
1465 |
+
return 'ecb';
|
1466 |
+
case CRYPT_MODE_CBC:
|
1467 |
+
return 'cbc';
|
1468 |
+
case CRYPT_MODE_CTR:
|
1469 |
+
return 'ctr';
|
1470 |
+
case CRYPT_MODE_CFB:
|
1471 |
+
return 'cfb';
|
1472 |
+
case CRYPT_MODE_OFB:
|
1473 |
+
return 'ofb';
|
1474 |
+
}
|
1475 |
+
}
|
1476 |
+
|
1477 |
+
/**
|
1478 |
+
* Pad "packets".
|
1479 |
+
*
|
1480 |
+
* Block ciphers working by encrypting between their specified [$this->]block_size at a time
|
1481 |
+
* If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to
|
1482 |
+
* pad the input so that it is of the proper length.
|
1483 |
+
*
|
1484 |
+
* Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH,
|
1485 |
+
* where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
|
1486 |
+
* away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
|
1487 |
+
* transmitted separately)
|
1488 |
+
*
|
1489 |
+
* @see Crypt_Base::disablePadding()
|
1490 |
+
* @access public
|
1491 |
+
*/
|
1492 |
+
function enablePadding()
|
1493 |
+
{
|
1494 |
+
$this->padding = true;
|
1495 |
+
}
|
1496 |
+
|
1497 |
+
/**
|
1498 |
+
* Do not pad packets.
|
1499 |
+
*
|
1500 |
+
* @see Crypt_Base::enablePadding()
|
1501 |
+
* @access public
|
1502 |
+
*/
|
1503 |
+
function disablePadding()
|
1504 |
+
{
|
1505 |
+
$this->padding = false;
|
1506 |
+
}
|
1507 |
+
|
1508 |
+
/**
|
1509 |
+
* Treat consecutive "packets" as if they are a continuous buffer.
|
1510 |
+
*
|
1511 |
+
* Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets
|
1512 |
+
* will yield different outputs:
|
1513 |
+
*
|
1514 |
+
* <code>
|
1515 |
+
* echo $rijndael->encrypt(substr($plaintext, 0, 16));
|
1516 |
+
* echo $rijndael->encrypt(substr($plaintext, 16, 16));
|
1517 |
+
* </code>
|
1518 |
+
* <code>
|
1519 |
+
* echo $rijndael->encrypt($plaintext);
|
1520 |
+
* </code>
|
1521 |
+
*
|
1522 |
+
* The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
|
1523 |
+
* another, as demonstrated with the following:
|
1524 |
+
*
|
1525 |
+
* <code>
|
1526 |
+
* $rijndael->encrypt(substr($plaintext, 0, 16));
|
1527 |
+
* echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
|
1528 |
+
* </code>
|
1529 |
+
* <code>
|
1530 |
+
* echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
|
1531 |
+
* </code>
|
1532 |
+
*
|
1533 |
+
* With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
|
1534 |
+
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
|
1535 |
+
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
|
1536 |
+
*
|
1537 |
+
* Put another way, when the continuous buffer is enabled, the state of the Crypt_*() object changes after each
|
1538 |
+
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
|
1539 |
+
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
|
1540 |
+
* however, they are also less intuitive and more likely to cause you problems.
|
1541 |
+
*
|
1542 |
+
* @see Crypt_Base::disableContinuousBuffer()
|
1543 |
+
* @access public
|
1544 |
+
* @internal Could, but not must, extend by the child Crypt_* class
|
1545 |
+
*/
|
1546 |
+
function enableContinuousBuffer()
|
1547 |
+
{
|
1548 |
+
if ($this->mode == CRYPT_MODE_ECB) {
|
1549 |
+
return;
|
1550 |
+
}
|
1551 |
+
|
1552 |
+
$this->continuousBuffer = true;
|
1553 |
+
|
1554 |
+
$this->_setEngine();
|
1555 |
+
}
|
1556 |
+
|
1557 |
+
/**
|
1558 |
+
* Treat consecutive packets as if they are a discontinuous buffer.
|
1559 |
+
*
|
1560 |
+
* The default behavior.
|
1561 |
+
*
|
1562 |
+
* @see Crypt_Base::enableContinuousBuffer()
|
1563 |
+
* @access public
|
1564 |
+
* @internal Could, but not must, extend by the child Crypt_* class
|
1565 |
+
*/
|
1566 |
+
function disableContinuousBuffer()
|
1567 |
+
{
|
1568 |
+
if ($this->mode == CRYPT_MODE_ECB) {
|
1569 |
+
return;
|
1570 |
+
}
|
1571 |
+
if (!$this->continuousBuffer) {
|
1572 |
+
return;
|
1573 |
+
}
|
1574 |
+
|
1575 |
+
$this->continuousBuffer = false;
|
1576 |
+
$this->changed = true;
|
1577 |
+
|
1578 |
+
$this->_setEngine();
|
1579 |
+
}
|
1580 |
+
|
1581 |
+
/**
|
1582 |
+
* Test for engine validity
|
1583 |
+
*
|
1584 |
+
* @see Crypt_Base::Crypt_Base()
|
1585 |
+
* @param int $engine
|
1586 |
+
* @access public
|
1587 |
+
* @return bool
|
1588 |
+
*/
|
1589 |
+
function isValidEngine($engine)
|
1590 |
+
{
|
1591 |
+
switch ($engine) {
|
1592 |
+
case CRYPT_ENGINE_OPENSSL:
|
1593 |
+
if ($this->mode == CRYPT_MODE_STREAM && $this->continuousBuffer) {
|
1594 |
+
return false;
|
1595 |
+
}
|
1596 |
+
$this->openssl_emulate_ctr = false;
|
1597 |
+
$result = $this->cipher_name_openssl &&
|
1598 |
+
extension_loaded('openssl') &&
|
1599 |
+
// PHP 5.3.0 - 5.3.2 did not let you set IV's
|
1600 |
+
version_compare(PHP_VERSION, '5.3.3', '>=');
|
1601 |
+
if (!$result) {
|
1602 |
+
return false;
|
1603 |
+
}
|
1604 |
+
|
1605 |
+
// prior to PHP 5.4.0 OPENSSL_RAW_DATA and OPENSSL_ZERO_PADDING were not defined. instead of expecting an integer
|
1606 |
+
// $options openssl_encrypt expected a boolean $raw_data.
|
1607 |
+
if (!defined('OPENSSL_RAW_DATA')) {
|
1608 |
+
$this->openssl_options = true;
|
1609 |
+
} else {
|
1610 |
+
$this->openssl_options = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING;
|
1611 |
+
}
|
1612 |
+
|
1613 |
+
$methods = openssl_get_cipher_methods();
|
1614 |
+
if (in_array($this->cipher_name_openssl, $methods)) {
|
1615 |
+
return true;
|
1616 |
+
}
|
1617 |
+
// not all of openssl's symmetric cipher's support ctr. for those
|
1618 |
+
// that don't we'll emulate it
|
1619 |
+
switch ($this->mode) {
|
1620 |
+
case CRYPT_MODE_CTR:
|
1621 |
+
if (in_array($this->cipher_name_openssl_ecb, $methods)) {
|
1622 |
+
$this->openssl_emulate_ctr = true;
|
1623 |
+
return true;
|
1624 |
+
}
|
1625 |
+
}
|
1626 |
+
return false;
|
1627 |
+
case CRYPT_ENGINE_MCRYPT:
|
1628 |
+
return $this->cipher_name_mcrypt &&
|
1629 |
+
extension_loaded('mcrypt') &&
|
1630 |
+
in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms());
|
1631 |
+
case CRYPT_ENGINE_INTERNAL:
|
1632 |
+
return true;
|
1633 |
+
}
|
1634 |
+
|
1635 |
+
return false;
|
1636 |
+
}
|
1637 |
+
|
1638 |
+
/**
|
1639 |
+
* Sets the preferred crypt engine
|
1640 |
+
*
|
1641 |
+
* Currently, $engine could be:
|
1642 |
+
*
|
1643 |
+
* - CRYPT_ENGINE_OPENSSL [very fast]
|
1644 |
+
*
|
1645 |
+
* - CRYPT_ENGINE_MCRYPT [fast]
|
1646 |
+
*
|
1647 |
+
* - CRYPT_ENGINE_INTERNAL [slow]
|
1648 |
+
*
|
1649 |
+
* If the preferred crypt engine is not available the fastest available one will be used
|
1650 |
+
*
|
1651 |
+
* @see Crypt_Base::Crypt_Base()
|
1652 |
+
* @param int $engine
|
1653 |
+
* @access public
|
1654 |
+
*/
|
1655 |
+
function setPreferredEngine($engine)
|
1656 |
+
{
|
1657 |
+
switch ($engine) {
|
1658 |
+
//case CRYPT_ENGINE_OPENSSL:
|
1659 |
+
case CRYPT_ENGINE_MCRYPT:
|
1660 |
+
case CRYPT_ENGINE_INTERNAL:
|
1661 |
+
$this->preferredEngine = $engine;
|
1662 |
+
break;
|
1663 |
+
default:
|
1664 |
+
$this->preferredEngine = CRYPT_ENGINE_OPENSSL;
|
1665 |
+
}
|
1666 |
+
|
1667 |
+
$this->_setEngine();
|
1668 |
+
}
|
1669 |
+
|
1670 |
+
/**
|
1671 |
+
* Returns the engine currently being utilized
|
1672 |
+
*
|
1673 |
+
* @see Crypt_Base::_setEngine()
|
1674 |
+
* @access public
|
1675 |
+
*/
|
1676 |
+
function getEngine()
|
1677 |
+
{
|
1678 |
+
return $this->engine;
|
1679 |
+
}
|
1680 |
+
|
1681 |
+
/**
|
1682 |
+
* Sets the engine as appropriate
|
1683 |
+
*
|
1684 |
+
* @see Crypt_Base::Crypt_Base()
|
1685 |
+
* @access private
|
1686 |
+
*/
|
1687 |
+
function _setEngine()
|
1688 |
+
{
|
1689 |
+
$this->engine = null;
|
1690 |
+
|
1691 |
+
$candidateEngines = array(
|
1692 |
+
$this->preferredEngine,
|
1693 |
+
CRYPT_ENGINE_OPENSSL,
|
1694 |
+
CRYPT_ENGINE_MCRYPT
|
1695 |
+
);
|
1696 |
+
foreach ($candidateEngines as $engine) {
|
1697 |
+
if ($this->isValidEngine($engine)) {
|
1698 |
+
$this->engine = $engine;
|
1699 |
+
break;
|
1700 |
+
}
|
1701 |
+
}
|
1702 |
+
if (!$this->engine) {
|
1703 |
+
$this->engine = CRYPT_ENGINE_INTERNAL;
|
1704 |
+
}
|
1705 |
+
|
1706 |
+
if ($this->engine != CRYPT_ENGINE_MCRYPT && $this->enmcrypt) {
|
1707 |
+
// Closing the current mcrypt resource(s). _mcryptSetup() will, if needed,
|
1708 |
+
// (re)open them with the module named in $this->cipher_name_mcrypt
|
1709 |
+
mcrypt_module_close($this->enmcrypt);
|
1710 |
+
mcrypt_module_close($this->demcrypt);
|
1711 |
+
$this->enmcrypt = null;
|
1712 |
+
$this->demcrypt = null;
|
1713 |
+
|
1714 |
+
if ($this->ecb) {
|
1715 |
+
mcrypt_module_close($this->ecb);
|
1716 |
+
$this->ecb = null;
|
1717 |
+
}
|
1718 |
+
}
|
1719 |
+
|
1720 |
+
$this->changed = true;
|
1721 |
+
}
|
1722 |
+
|
1723 |
+
/**
|
1724 |
+
* Encrypts a block
|
1725 |
+
*
|
1726 |
+
* @access private
|
1727 |
+
* @param string $in
|
1728 |
+
* @return string
|
1729 |
+
* @internal Must be extended by the child Crypt_* class
|
1730 |
+
*/
|
1731 |
+
function _encryptBlock($in)
|
1732 |
+
{
|
1733 |
+
user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
|
1734 |
+
}
|
1735 |
+
|
1736 |
+
/**
|
1737 |
+
* Decrypts a block
|
1738 |
+
*
|
1739 |
+
* @access private
|
1740 |
+
* @param string $in
|
1741 |
+
* @return string
|
1742 |
+
* @internal Must be extended by the child Crypt_* class
|
1743 |
+
*/
|
1744 |
+
function _decryptBlock($in)
|
1745 |
+
{
|
1746 |
+
user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
|
1747 |
+
}
|
1748 |
+
|
1749 |
+
/**
|
1750 |
+
* Setup the key (expansion)
|
1751 |
+
*
|
1752 |
+
* Only used if $engine == CRYPT_ENGINE_INTERNAL
|
1753 |
+
*
|
1754 |
+
* @see Crypt_Base::_setup()
|
1755 |
+
* @access private
|
1756 |
+
* @internal Must be extended by the child Crypt_* class
|
1757 |
+
*/
|
1758 |
+
function _setupKey()
|
1759 |
+
{
|
1760 |
+
user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
|
1761 |
+
}
|
1762 |
+
|
1763 |
+
/**
|
1764 |
+
* Setup the CRYPT_ENGINE_INTERNAL $engine
|
1765 |
+
*
|
1766 |
+
* (re)init, if necessary, the internal cipher $engine and flush all $buffers
|
1767 |
+
* Used (only) if $engine == CRYPT_ENGINE_INTERNAL
|
1768 |
+
*
|
1769 |
+
* _setup() will be called each time if $changed === true
|
1770 |
+
* typically this happens when using one or more of following public methods:
|
1771 |
+
*
|
1772 |
+
* - setKey()
|
1773 |
+
*
|
1774 |
+
* - setIV()
|
1775 |
+
*
|
1776 |
+
* - disableContinuousBuffer()
|
1777 |
+
*
|
1778 |
+
* - First run of encrypt() / decrypt() with no init-settings
|
1779 |
+
*
|
1780 |
+
* @see setKey()
|
1781 |
+
* @see setIV()
|
1782 |
+
* @see disableContinuousBuffer()
|
1783 |
+
* @access private
|
1784 |
+
* @internal _setup() is always called before en/decryption.
|
1785 |
+
* @internal Could, but not must, extend by the child Crypt_* class
|
1786 |
+
*/
|
1787 |
+
function _setup()
|
1788 |
+
{
|
1789 |
+
$this->_clearBuffers();
|
1790 |
+
$this->_setupKey();
|
1791 |
+
|
1792 |
+
if ($this->use_inline_crypt) {
|
1793 |
+
$this->_setupInlineCrypt();
|
1794 |
+
}
|
1795 |
+
}
|
1796 |
+
|
1797 |
+
/**
|
1798 |
+
* Setup the CRYPT_ENGINE_MCRYPT $engine
|
1799 |
+
*
|
1800 |
+
* (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers
|
1801 |
+
* Used (only) if $engine = CRYPT_ENGINE_MCRYPT
|
1802 |
+
*
|
1803 |
+
* _setupMcrypt() will be called each time if $changed === true
|
1804 |
+
* typically this happens when using one or more of following public methods:
|
1805 |
+
*
|
1806 |
+
* - setKey()
|
1807 |
+
*
|
1808 |
+
* - setIV()
|
1809 |
+
*
|
1810 |
+
* - disableContinuousBuffer()
|
1811 |
+
*
|
1812 |
+
* - First run of encrypt() / decrypt()
|
1813 |
+
*
|
1814 |
+
* @see setKey()
|
1815 |
+
* @see setIV()
|
1816 |
+
* @see disableContinuousBuffer()
|
1817 |
+
* @access private
|
1818 |
+
* @internal Could, but not must, extend by the child Crypt_* class
|
1819 |
+
*/
|
1820 |
+
function _setupMcrypt()
|
1821 |
+
{
|
1822 |
+
$this->_clearBuffers();
|
1823 |
+
$this->enchanged = $this->dechanged = true;
|
1824 |
+
|
1825 |
+
if (!isset($this->enmcrypt)) {
|
1826 |
+
static $mcrypt_modes = array(
|
1827 |
+
CRYPT_MODE_CTR => 'ctr',
|
1828 |
+
CRYPT_MODE_ECB => MCRYPT_MODE_ECB,
|
1829 |
+
CRYPT_MODE_CBC => MCRYPT_MODE_CBC,
|
1830 |
+
CRYPT_MODE_CFB => 'ncfb',
|
1831 |
+
CRYPT_MODE_OFB => MCRYPT_MODE_NOFB,
|
1832 |
+
CRYPT_MODE_STREAM => MCRYPT_MODE_STREAM,
|
1833 |
+
);
|
1834 |
+
|
1835 |
+
$this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
|
1836 |
+
$this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
|
1837 |
+
|
1838 |
+
// we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer()
|
1839 |
+
// to workaround mcrypt's broken ncfb implementation in buffered mode
|
1840 |
+
// see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
|
1841 |
+
if ($this->mode == CRYPT_MODE_CFB) {
|
1842 |
+
$this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
|
1843 |
+
}
|
1844 |
+
} // else should mcrypt_generic_deinit be called?
|
1845 |
+
|
1846 |
+
if ($this->mode == CRYPT_MODE_CFB) {
|
1847 |
+
mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
|
1848 |
+
}
|
1849 |
+
}
|
1850 |
+
|
1851 |
+
/**
|
1852 |
+
* Pads a string
|
1853 |
+
*
|
1854 |
+
* Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize.
|
1855 |
+
* $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to
|
1856 |
+
* chr($this->block_size - (strlen($text) % $this->block_size)
|
1857 |
+
*
|
1858 |
+
* If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
|
1859 |
+
* and padding will, hence forth, be enabled.
|
1860 |
+
*
|
1861 |
+
* @see Crypt_Base::_unpad()
|
1862 |
+
* @param string $text
|
1863 |
+
* @access private
|
1864 |
+
* @return string
|
1865 |
+
*/
|
1866 |
+
function _pad($text)
|
1867 |
+
{
|
1868 |
+
$length = strlen($text);
|
1869 |
+
|
1870 |
+
if (!$this->padding) {
|
1871 |
+
if ($length % $this->block_size == 0) {
|
1872 |
+
return $text;
|
1873 |
+
} else {
|
1874 |
+
user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})");
|
1875 |
+
$this->padding = true;
|
1876 |
+
}
|
1877 |
+
}
|
1878 |
+
|
1879 |
+
$pad = $this->block_size - ($length % $this->block_size);
|
1880 |
+
|
1881 |
+
return str_pad($text, $length + $pad, chr($pad));
|
1882 |
+
}
|
1883 |
+
|
1884 |
+
/**
|
1885 |
+
* Unpads a string.
|
1886 |
+
*
|
1887 |
+
* If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
|
1888 |
+
* and false will be returned.
|
1889 |
+
*
|
1890 |
+
* @see Crypt_Base::_pad()
|
1891 |
+
* @param string $text
|
1892 |
+
* @access private
|
1893 |
+
* @return string
|
1894 |
+
*/
|
1895 |
+
function _unpad($text)
|
1896 |
+
{
|
1897 |
+
if (!$this->padding) {
|
1898 |
+
return $text;
|
1899 |
+
}
|
1900 |
+
|
1901 |
+
$length = ord($text[strlen($text) - 1]);
|
1902 |
+
|
1903 |
+
if (!$length || $length > $this->block_size) {
|
1904 |
+
return false;
|
1905 |
+
}
|
1906 |
+
|
1907 |
+
return substr($text, 0, -$length);
|
1908 |
+
}
|
1909 |
+
|
1910 |
+
/**
|
1911 |
+
* Clears internal buffers
|
1912 |
+
*
|
1913 |
+
* Clearing/resetting the internal buffers is done everytime
|
1914 |
+
* after disableContinuousBuffer() or on cipher $engine (re)init
|
1915 |
+
* ie after setKey() or setIV()
|
1916 |
+
*
|
1917 |
+
* @access public
|
1918 |
+
* @internal Could, but not must, extend by the child Crypt_* class
|
1919 |
+
*/
|
1920 |
+
function _clearBuffers()
|
1921 |
+
{
|
1922 |
+
$this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
|
1923 |
+
|
1924 |
+
// mcrypt's handling of invalid's $iv:
|
1925 |
+
// $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size);
|
1926 |
+
$this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");
|
1927 |
+
|
1928 |
+
if (!$this->skip_key_adjustment) {
|
1929 |
+
$this->key = str_pad(substr($this->key, 0, $this->key_length), $this->key_length, "\0");
|
1930 |
+
}
|
1931 |
+
}
|
1932 |
+
|
1933 |
+
/**
|
1934 |
+
* String Shift
|
1935 |
+
*
|
1936 |
+
* Inspired by array_shift
|
1937 |
+
*
|
1938 |
+
* @param string $string
|
1939 |
+
* @param int $index
|
1940 |
+
* @access private
|
1941 |
+
* @return string
|
1942 |
+
*/
|
1943 |
+
function _string_shift(&$string, $index = 1)
|
1944 |
+
{
|
1945 |
+
$substr = substr($string, 0, $index);
|
1946 |
+
$string = substr($string, $index);
|
1947 |
+
return $substr;
|
1948 |
+
}
|
1949 |
+
|
1950 |
+
/**
|
1951 |
+
* String Pop
|
1952 |
+
*
|
1953 |
+
* Inspired by array_pop
|
1954 |
+
*
|
1955 |
+
* @param string $string
|
1956 |
+
* @param int $index
|
1957 |
+
* @access private
|
1958 |
+
* @return string
|
1959 |
+
*/
|
1960 |
+
function _string_pop(&$string, $index = 1)
|
1961 |
+
{
|
1962 |
+
$substr = substr($string, -$index);
|
1963 |
+
$string = substr($string, 0, -$index);
|
1964 |
+
return $substr;
|
1965 |
+
}
|
1966 |
+
|
1967 |
+
/**
|
1968 |
+
* Increment the current string
|
1969 |
+
*
|
1970 |
+
* @see Crypt_Base::decrypt()
|
1971 |
+
* @see Crypt_Base::encrypt()
|
1972 |
+
* @param string $var
|
1973 |
+
* @access private
|
1974 |
+
*/
|
1975 |
+
function _increment_str(&$var)
|
1976 |
+
{
|
1977 |
+
for ($i = 4; $i <= strlen($var); $i+= 4) {
|
1978 |
+
$temp = substr($var, -$i, 4);
|
1979 |
+
switch ($temp) {
|
1980 |
+
case "\xFF\xFF\xFF\xFF":
|
1981 |
+
$var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4);
|
1982 |
+
break;
|
1983 |
+
case "\x7F\xFF\xFF\xFF":
|
1984 |
+
$var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4);
|
1985 |
+
return;
|
1986 |
+
default:
|
1987 |
+
$temp = unpack('Nnum', $temp);
|
1988 |
+
$var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4);
|
1989 |
+
return;
|
1990 |
+
}
|
1991 |
+
}
|
1992 |
+
|
1993 |
+
$remainder = strlen($var) % 4;
|
1994 |
+
|
1995 |
+
if ($remainder == 0) {
|
1996 |
+
return;
|
1997 |
+
}
|
1998 |
+
|
1999 |
+
$temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT));
|
2000 |
+
$temp = substr(pack('N', $temp['num'] + 1), -$remainder);
|
2001 |
+
$var = substr_replace($var, $temp, 0, $remainder);
|
2002 |
+
}
|
2003 |
+
|
2004 |
+
/**
|
2005 |
+
* Setup the performance-optimized function for de/encrypt()
|
2006 |
+
*
|
2007 |
+
* Stores the created (or existing) callback function-name
|
2008 |
+
* in $this->inline_crypt
|
2009 |
+
*
|
2010 |
+
* Internally for phpseclib developers:
|
2011 |
+
*
|
2012 |
+
* _setupInlineCrypt() would be called only if:
|
2013 |
+
*
|
2014 |
+
* - $engine == CRYPT_ENGINE_INTERNAL and
|
2015 |
+
*
|
2016 |
+
* - $use_inline_crypt === true
|
2017 |
+
*
|
2018 |
+
* - each time on _setup(), after(!) _setupKey()
|
2019 |
+
*
|
2020 |
+
*
|
2021 |
+
* This ensures that _setupInlineCrypt() has always a
|
2022 |
+
* full ready2go initializated internal cipher $engine state
|
2023 |
+
* where, for example, the keys allready expanded,
|
2024 |
+
* keys/block_size calculated and such.
|
2025 |
+
*
|
2026 |
+
* It is, each time if called, the responsibility of _setupInlineCrypt():
|
2027 |
+
*
|
2028 |
+
* - to set $this->inline_crypt to a valid and fully working callback function
|
2029 |
+
* as a (faster) replacement for encrypt() / decrypt()
|
2030 |
+
*
|
2031 |
+
* - NOT to create unlimited callback functions (for memory reasons!)
|
2032 |
+
* no matter how often _setupInlineCrypt() would be called. At some
|
2033 |
+
* point of amount they must be generic re-useable.
|
2034 |
+
*
|
2035 |
+
* - the code of _setupInlineCrypt() it self,
|
2036 |
+
* and the generated callback code,
|
2037 |
+
* must be, in following order:
|
2038 |
+
* - 100% safe
|
2039 |
+
* - 100% compatible to encrypt()/decrypt()
|
2040 |
+
* - using only php5+ features/lang-constructs/php-extensions if
|
2041 |
+
* compatibility (down to php4) or fallback is provided
|
2042 |
+
* - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-)
|
2043 |
+
* - >= 10% faster than encrypt()/decrypt() [which is, by the way,
|
2044 |
+
* the reason for the existence of _setupInlineCrypt() :-)]
|
2045 |
+
* - memory-nice
|
2046 |
+
* - short (as good as possible)
|
2047 |
+
*
|
2048 |
+
* Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code.
|
2049 |
+
* - In case of using inline crypting, _setupInlineCrypt() must extend by the child Crypt_* class.
|
2050 |
+
* - The following variable names are reserved:
|
2051 |
+
* - $_* (all variable names prefixed with an underscore)
|
2052 |
+
* - $self (object reference to it self. Do not use $this, but $self instead)
|
2053 |
+
* - $in (the content of $in has to en/decrypt by the generated code)
|
2054 |
+
* - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only
|
2055 |
+
*
|
2056 |
+
*
|
2057 |
+
* @see Crypt_Base::_setup()
|
2058 |
+
* @see Crypt_Base::_createInlineCryptFunction()
|
2059 |
+
* @see Crypt_Base::encrypt()
|
2060 |
+
* @see Crypt_Base::decrypt()
|
2061 |
+
* @access private
|
2062 |
+
* @internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()
|
2063 |
+
*/
|
2064 |
+
function _setupInlineCrypt()
|
2065 |
+
{
|
2066 |
+
// If, for any reason, an extending Crypt_Base() Crypt_* class
|
2067 |
+
// not using inline crypting then it must be ensured that: $this->use_inline_crypt = false
|
2068 |
+
// ie in the class var declaration of $use_inline_crypt in general for the Crypt_* class,
|
2069 |
+
// in the constructor at object instance-time
|
2070 |
+
// or, if it's runtime-specific, at runtime
|
2071 |
+
|
2072 |
+
$this->use_inline_crypt = false;
|
2073 |
+
}
|
2074 |
+
|
2075 |
+
/**
|
2076 |
+
* Creates the performance-optimized function for en/decrypt()
|
2077 |
+
*
|
2078 |
+
* Internally for phpseclib developers:
|
2079 |
+
*
|
2080 |
+
* _createInlineCryptFunction():
|
2081 |
+
*
|
2082 |
+
* - merge the $cipher_code [setup'ed by _setupInlineCrypt()]
|
2083 |
+
* with the current [$this->]mode of operation code
|
2084 |
+
*
|
2085 |
+
* - create the $inline function, which called by encrypt() / decrypt()
|
2086 |
+
* as its replacement to speed up the en/decryption operations.
|
2087 |
+
*
|
2088 |
+
* - return the name of the created $inline callback function
|
2089 |
+
*
|
2090 |
+
* - used to speed up en/decryption
|
2091 |
+
*
|
2092 |
+
*
|
2093 |
+
*
|
2094 |
+
* The main reason why can speed up things [up to 50%] this way are:
|
2095 |
+
*
|
2096 |
+
* - using variables more effective then regular.
|
2097 |
+
* (ie no use of expensive arrays but integers $k_0, $k_1 ...
|
2098 |
+
* or even, for example, the pure $key[] values hardcoded)
|
2099 |
+
*
|
2100 |
+
* - avoiding 1000's of function calls of ie _encryptBlock()
|
2101 |
+
* but inlining the crypt operations.
|
2102 |
+
* in the mode of operation for() loop.
|
2103 |
+
*
|
2104 |
+
* - full loop unroll the (sometimes key-dependent) rounds
|
2105 |
+
* avoiding this way ++$i counters and runtime-if's etc...
|
2106 |
+
*
|
2107 |
+
* The basic code architectur of the generated $inline en/decrypt()
|
2108 |
+
* lambda function, in pseudo php, is:
|
2109 |
+
*
|
2110 |
+
* <code>
|
2111 |
+
* +----------------------------------------------------------------------------------------------+
|
2112 |
+
* | callback $inline = create_function: |
|
2113 |
+
* | lambda_function_0001_crypt_ECB($action, $text) |
|
2114 |
+
* | { |
|
2115 |
+
* | INSERT PHP CODE OF: |
|
2116 |
+
* | $cipher_code['init_crypt']; // general init code. |
|
2117 |
+
* | // ie: $sbox'es declarations used for |
|
2118 |
+
* | // encrypt and decrypt'ing. |
|
2119 |
+
* | |
|
2120 |
+
* | switch ($action) { |
|
2121 |
+
* | case 'encrypt': |
|
2122 |
+
* | INSERT PHP CODE OF: |
|
2123 |
+
* | $cipher_code['init_encrypt']; // encrypt sepcific init code. |
|
2124 |
+
* | ie: specified $key or $box |
|
2125 |
+
* | declarations for encrypt'ing. |
|
2126 |
+
* | |
|
2127 |
+
* | foreach ($ciphertext) { |
|
2128 |
+
* | $in = $block_size of $ciphertext; |
|
2129 |
+
* | |
|
2130 |
+
* | INSERT PHP CODE OF: |
|
2131 |
+
* | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: |
|
2132 |
+
* | // strlen($in) == $this->block_size |
|
2133 |
+
* | // here comes the cipher algorithm in action |
|
2134 |
+
* | // for encryption. |
|
2135 |
+
* | // $cipher_code['encrypt_block'] has to |
|
2136 |
+
* | // encrypt the content of the $in variable |
|
2137 |
+
* | |
|
2138 |
+
* | $plaintext .= $in; |
|
2139 |
+
* | } |
|
2140 |
+
* | return $plaintext; |
|
2141 |
+
* | |
|
2142 |
+
* | case 'decrypt': |
|
2143 |
+
* | INSERT PHP CODE OF: |
|
2144 |
+
* | $cipher_code['init_decrypt']; // decrypt sepcific init code |
|
2145 |
+
* | ie: specified $key or $box |
|
2146 |
+
* | declarations for decrypt'ing. |
|
2147 |
+
* | foreach ($plaintext) { |
|
2148 |
+
* | $in = $block_size of $plaintext; |
|
2149 |
+
* | |
|
2150 |
+
* | INSERT PHP CODE OF: |
|
2151 |
+
* | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always |
|
2152 |
+
* | // strlen($in) == $this->block_size |
|
2153 |
+
* | // here comes the cipher algorithm in action |
|
2154 |
+
* | // for decryption. |
|
2155 |
+
* | // $cipher_code['decrypt_block'] has to |
|
2156 |
+
* | // decrypt the content of the $in variable |
|
2157 |
+
* | $ciphertext .= $in; |
|
2158 |
+
* | } |
|
2159 |
+
* | return $ciphertext; |
|
2160 |
+
* | } |
|
2161 |
+
* | } |
|
2162 |
+
* +----------------------------------------------------------------------------------------------+
|
2163 |
+
* </code>
|
2164 |
+
*
|
2165 |
+
* See also the Crypt_*::_setupInlineCrypt()'s for
|
2166 |
+
* productive inline $cipher_code's how they works.
|
2167 |
+
*
|
2168 |
+
* Structure of:
|
2169 |
+
* <code>
|
2170 |
+
* $cipher_code = array(
|
2171 |
+
* 'init_crypt' => (string) '', // optional
|
2172 |
+
* 'init_encrypt' => (string) '', // optional
|
2173 |
+
* 'init_decrypt' => (string) '', // optional
|
2174 |
+
* 'encrypt_block' => (string) '', // required
|
2175 |
+
* 'decrypt_block' => (string) '' // required
|
2176 |
+
* );
|
2177 |
+
* </code>
|
2178 |
+
*
|
2179 |
+
* @see Crypt_Base::_setupInlineCrypt()
|
2180 |
+
* @see Crypt_Base::encrypt()
|
2181 |
+
* @see Crypt_Base::decrypt()
|
2182 |
+
* @param array $cipher_code
|
2183 |
+
* @access private
|
2184 |
+
* @return string (the name of the created callback function)
|
2185 |
+
*/
|
2186 |
+
function _createInlineCryptFunction($cipher_code)
|
2187 |
+
{
|
2188 |
+
$block_size = $this->block_size;
|
2189 |
+
|
2190 |
+
// optional
|
2191 |
+
$init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : '';
|
2192 |
+
$init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : '';
|
2193 |
+
$init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : '';
|
2194 |
+
// required
|
2195 |
+
$encrypt_block = $cipher_code['encrypt_block'];
|
2196 |
+
$decrypt_block = $cipher_code['decrypt_block'];
|
2197 |
+
|
2198 |
+
// Generating mode of operation inline code,
|
2199 |
+
// merged with the $cipher_code algorithm
|
2200 |
+
// for encrypt- and decryption.
|
2201 |
+
switch ($this->mode) {
|
2202 |
+
case CRYPT_MODE_ECB:
|
2203 |
+
$encrypt = $init_encrypt . '
|
2204 |
+
$_ciphertext = "";
|
2205 |
+
$_plaintext_len = strlen($_text);
|
2206 |
+
|
2207 |
+
for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
|
2208 |
+
$in = substr($_text, $_i, '.$block_size.');
|
2209 |
+
'.$encrypt_block.'
|
2210 |
+
$_ciphertext.= $in;
|
2211 |
+
}
|
2212 |
+
|
2213 |
+
return $_ciphertext;
|
2214 |
+
';
|
2215 |
+
|
2216 |
+
$decrypt = $init_decrypt . '
|
2217 |
+
$_plaintext = "";
|
2218 |
+
$_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
|
2219 |
+
$_ciphertext_len = strlen($_text);
|
2220 |
+
|
2221 |
+
for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
|
2222 |
+
$in = substr($_text, $_i, '.$block_size.');
|
2223 |
+
'.$decrypt_block.'
|
2224 |
+
$_plaintext.= $in;
|
2225 |
+
}
|
2226 |
+
|
2227 |
+
return $self->_unpad($_plaintext);
|
2228 |
+
';
|
2229 |
+
break;
|
2230 |
+
case CRYPT_MODE_CTR:
|
2231 |
+
$encrypt = $init_encrypt . '
|
2232 |
+
$_ciphertext = "";
|
2233 |
+
$_plaintext_len = strlen($_text);
|
2234 |
+
$_xor = $self->encryptIV;
|
2235 |
+
$_buffer = &$self->enbuffer;
|
2236 |
+
if (strlen($_buffer["ciphertext"])) {
|
2237 |
+
for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
|
2238 |
+
$_block = substr($_text, $_i, '.$block_size.');
|
2239 |
+
if (strlen($_block) > strlen($_buffer["ciphertext"])) {
|
2240 |
+
$in = $_xor;
|
2241 |
+
'.$encrypt_block.'
|
2242 |
+
$self->_increment_str($_xor);
|
2243 |
+
$_buffer["ciphertext"].= $in;
|
2244 |
+
}
|
2245 |
+
$_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
|
2246 |
+
$_ciphertext.= $_block ^ $_key;
|
2247 |
+
}
|
2248 |
+
} else {
|
2249 |
+
for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
|
2250 |
+
$_block = substr($_text, $_i, '.$block_size.');
|
2251 |
+
$in = $_xor;
|
2252 |
+
'.$encrypt_block.'
|
2253 |
+
$self->_increment_str($_xor);
|
2254 |
+
$_key = $in;
|
2255 |
+
$_ciphertext.= $_block ^ $_key;
|
2256 |
+
}
|
2257 |
+
}
|
2258 |
+
if ($self->continuousBuffer) {
|
2259 |
+
$self->encryptIV = $_xor;
|
2260 |
+
if ($_start = $_plaintext_len % '.$block_size.') {
|
2261 |
+
$_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
|
2262 |
+
}
|
2263 |
+
}
|
2264 |
+
|
2265 |
+
return $_ciphertext;
|
2266 |
+
';
|
2267 |
+
|
2268 |
+
$decrypt = $init_encrypt . '
|
2269 |
+
$_plaintext = "";
|
2270 |
+
$_ciphertext_len = strlen($_text);
|
2271 |
+
$_xor = $self->decryptIV;
|
2272 |
+
$_buffer = &$self->debuffer;
|
2273 |
+
|
2274 |
+
if (strlen($_buffer["ciphertext"])) {
|
2275 |
+
for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
|
2276 |
+
$_block = substr($_text, $_i, '.$block_size.');
|
2277 |
+
if (strlen($_block) > strlen($_buffer["ciphertext"])) {
|
2278 |
+
$in = $_xor;
|
2279 |
+
'.$encrypt_block.'
|
2280 |
+
$self->_increment_str($_xor);
|
2281 |
+
$_buffer["ciphertext"].= $in;
|
2282 |
+
}
|
2283 |
+
$_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
|
2284 |
+
$_plaintext.= $_block ^ $_key;
|
2285 |
+
}
|
2286 |
+
} else {
|
2287 |
+
for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
|
2288 |
+
$_block = substr($_text, $_i, '.$block_size.');
|
2289 |
+
$in = $_xor;
|
2290 |
+
'.$encrypt_block.'
|
2291 |
+
$self->_increment_str($_xor);
|
2292 |
+
$_key = $in;
|
2293 |
+
$_plaintext.= $_block ^ $_key;
|
2294 |
+
}
|
2295 |
+
}
|
2296 |
+
if ($self->continuousBuffer) {
|
2297 |
+
$self->decryptIV = $_xor;
|
2298 |
+
if ($_start = $_ciphertext_len % '.$block_size.') {
|
2299 |
+
$_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
|
2300 |
+
}
|
2301 |
+
}
|
2302 |
+
|
2303 |
+
return $_plaintext;
|
2304 |
+
';
|
2305 |
+
break;
|
2306 |
+
case CRYPT_MODE_CFB:
|
2307 |
+
$encrypt = $init_encrypt . '
|
2308 |
+
$_ciphertext = "";
|
2309 |
+
$_buffer = &$self->enbuffer;
|
2310 |
+
|
2311 |
+
if ($self->continuousBuffer) {
|
2312 |
+
$_iv = &$self->encryptIV;
|
2313 |
+
$_pos = &$_buffer["pos"];
|
2314 |
+
} else {
|
2315 |
+
$_iv = $self->encryptIV;
|
2316 |
+
$_pos = 0;
|
2317 |
+
}
|
2318 |
+
$_len = strlen($_text);
|
2319 |
+
$_i = 0;
|
2320 |
+
if ($_pos) {
|
2321 |
+
$_orig_pos = $_pos;
|
2322 |
+
$_max = '.$block_size.' - $_pos;
|
2323 |
+
if ($_len >= $_max) {
|
2324 |
+
$_i = $_max;
|
2325 |
+
$_len-= $_max;
|
2326 |
+
$_pos = 0;
|
2327 |
+
} else {
|
2328 |
+
$_i = $_len;
|
2329 |
+
$_pos+= $_len;
|
2330 |
+
$_len = 0;
|
2331 |
+
}
|
2332 |
+
$_ciphertext = substr($_iv, $_orig_pos) ^ $_text;
|
2333 |
+
$_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i);
|
2334 |
+
}
|
2335 |
+
while ($_len >= '.$block_size.') {
|
2336 |
+
$in = $_iv;
|
2337 |
+
'.$encrypt_block.';
|
2338 |
+
$_iv = $in ^ substr($_text, $_i, '.$block_size.');
|
2339 |
+
$_ciphertext.= $_iv;
|
2340 |
+
$_len-= '.$block_size.';
|
2341 |
+
$_i+= '.$block_size.';
|
2342 |
+
}
|
2343 |
+
if ($_len) {
|
2344 |
+
$in = $_iv;
|
2345 |
+
'.$encrypt_block.'
|
2346 |
+
$_iv = $in;
|
2347 |
+
$_block = $_iv ^ substr($_text, $_i);
|
2348 |
+
$_iv = substr_replace($_iv, $_block, 0, $_len);
|
2349 |
+
$_ciphertext.= $_block;
|
2350 |
+
$_pos = $_len;
|
2351 |
+
}
|
2352 |
+
return $_ciphertext;
|
2353 |
+
';
|
2354 |
+
|
2355 |
+
$decrypt = $init_encrypt . '
|
2356 |
+
$_plaintext = "";
|
2357 |
+
$_buffer = &$self->debuffer;
|
2358 |
+
|
2359 |
+
if ($self->continuousBuffer) {
|
2360 |
+
$_iv = &$self->decryptIV;
|
2361 |
+
$_pos = &$_buffer["pos"];
|
2362 |
+
} else {
|
2363 |
+
$_iv = $self->decryptIV;
|
2364 |
+
$_pos = 0;
|
2365 |
+
}
|
2366 |
+
$_len = strlen($_text);
|
2367 |
+
$_i = 0;
|
2368 |
+
if ($_pos) {
|
2369 |
+
$_orig_pos = $_pos;
|
2370 |
+
$_max = '.$block_size.' - $_pos;
|
2371 |
+
if ($_len >= $_max) {
|
2372 |
+
$_i = $_max;
|
2373 |
+
$_len-= $_max;
|
2374 |
+
$_pos = 0;
|
2375 |
+
} else {
|
2376 |
+
$_i = $_len;
|
2377 |
+
$_pos+= $_len;
|
2378 |
+
$_len = 0;
|
2379 |
+
}
|
2380 |
+
$_plaintext = substr($_iv, $_orig_pos) ^ $_text;
|
2381 |
+
$_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i);
|
2382 |
+
}
|
2383 |
+
while ($_len >= '.$block_size.') {
|
2384 |
+
$in = $_iv;
|
2385 |
+
'.$encrypt_block.'
|
2386 |
+
$_iv = $in;
|
2387 |
+
$cb = substr($_text, $_i, '.$block_size.');
|
2388 |
+
$_plaintext.= $_iv ^ $cb;
|
2389 |
+
$_iv = $cb;
|
2390 |
+
$_len-= '.$block_size.';
|
2391 |
+
$_i+= '.$block_size.';
|
2392 |
+
}
|
2393 |
+
if ($_len) {
|
2394 |
+
$in = $_iv;
|
2395 |
+
'.$encrypt_block.'
|
2396 |
+
$_iv = $in;
|
2397 |
+
$_plaintext.= $_iv ^ substr($_text, $_i);
|
2398 |
+
$_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len);
|
2399 |
+
$_pos = $_len;
|
2400 |
+
}
|
2401 |
+
|
2402 |
+
return $_plaintext;
|
2403 |
+
';
|
2404 |
+
break;
|
2405 |
+
case CRYPT_MODE_OFB:
|
2406 |
+
$encrypt = $init_encrypt . '
|
2407 |
+
$_ciphertext = "";
|
2408 |
+
$_plaintext_len = strlen($_text);
|
2409 |
+
$_xor = $self->encryptIV;
|
2410 |
+
$_buffer = &$self->enbuffer;
|
2411 |
+
|
2412 |
+
if (strlen($_buffer["xor"])) {
|
2413 |
+
for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
|
2414 |
+
$_block = substr($_text, $_i, '.$block_size.');
|
2415 |
+
if (strlen($_block) > strlen($_buffer["xor"])) {
|
2416 |
+
$in = $_xor;
|
2417 |
+
'.$encrypt_block.'
|
2418 |
+
$_xor = $in;
|
2419 |
+
$_buffer["xor"].= $_xor;
|
2420 |
+
}
|
2421 |
+
$_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
|
2422 |
+
$_ciphertext.= $_block ^ $_key;
|
2423 |
+
}
|
2424 |
+
} else {
|
2425 |
+
for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
|
2426 |
+
$in = $_xor;
|
2427 |
+
'.$encrypt_block.'
|
2428 |
+
$_xor = $in;
|
2429 |
+
$_ciphertext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
|
2430 |
+
}
|
2431 |
+
$_key = $_xor;
|
2432 |
+
}
|
2433 |
+
if ($self->continuousBuffer) {
|
2434 |
+
$self->encryptIV = $_xor;
|
2435 |
+
if ($_start = $_plaintext_len % '.$block_size.') {
|
2436 |
+
$_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
|
2437 |
+
}
|
2438 |
+
}
|
2439 |
+
return $_ciphertext;
|
2440 |
+
';
|
2441 |
+
|
2442 |
+
$decrypt = $init_encrypt . '
|
2443 |
+
$_plaintext = "";
|
2444 |
+
$_ciphertext_len = strlen($_text);
|
2445 |
+
$_xor = $self->decryptIV;
|
2446 |
+
$_buffer = &$self->debuffer;
|
2447 |
+
|
2448 |
+
if (strlen($_buffer["xor"])) {
|
2449 |
+
for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
|
2450 |
+
$_block = substr($_text, $_i, '.$block_size.');
|
2451 |
+
if (strlen($_block) > strlen($_buffer["xor"])) {
|
2452 |
+
$in = $_xor;
|
2453 |
+
'.$encrypt_block.'
|
2454 |
+
$_xor = $in;
|
2455 |
+
$_buffer["xor"].= $_xor;
|
2456 |
+
}
|
2457 |
+
$_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
|
2458 |
+
$_plaintext.= $_block ^ $_key;
|
2459 |
+
}
|
2460 |
+
} else {
|
2461 |
+
for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
|
2462 |
+
$in = $_xor;
|
2463 |
+
'.$encrypt_block.'
|
2464 |
+
$_xor = $in;
|
2465 |
+
$_plaintext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
|
2466 |
+
}
|
2467 |
+
$_key = $_xor;
|
2468 |
+
}
|
2469 |
+
if ($self->continuousBuffer) {
|
2470 |
+
$self->decryptIV = $_xor;
|
2471 |
+
if ($_start = $_ciphertext_len % '.$block_size.') {
|
2472 |
+
$_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
|
2473 |
+
}
|
2474 |
+
}
|
2475 |
+
return $_plaintext;
|
2476 |
+
';
|
2477 |
+
break;
|
2478 |
+
case CRYPT_MODE_STREAM:
|
2479 |
+
$encrypt = $init_encrypt . '
|
2480 |
+
$_ciphertext = "";
|
2481 |
+
'.$encrypt_block.'
|
2482 |
+
return $_ciphertext;
|
2483 |
+
';
|
2484 |
+
$decrypt = $init_decrypt . '
|
2485 |
+
$_plaintext = "";
|
2486 |
+
'.$decrypt_block.'
|
2487 |
+
return $_plaintext;
|
2488 |
+
';
|
2489 |
+
break;
|
2490 |
+
// case CRYPT_MODE_CBC:
|
2491 |
+
default:
|
2492 |
+
$encrypt = $init_encrypt . '
|
2493 |
+
$_ciphertext = "";
|
2494 |
+
$_plaintext_len = strlen($_text);
|
2495 |
+
|
2496 |
+
$in = $self->encryptIV;
|
2497 |
+
|
2498 |
+
for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
|
2499 |
+
$in = substr($_text, $_i, '.$block_size.') ^ $in;
|
2500 |
+
'.$encrypt_block.'
|
2501 |
+
$_ciphertext.= $in;
|
2502 |
+
}
|
2503 |
+
|
2504 |
+
if ($self->continuousBuffer) {
|
2505 |
+
$self->encryptIV = $in;
|
2506 |
+
}
|
2507 |
+
|
2508 |
+
return $_ciphertext;
|
2509 |
+
';
|
2510 |
+
|
2511 |
+
$decrypt = $init_decrypt . '
|
2512 |
+
$_plaintext = "";
|
2513 |
+
$_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
|
2514 |
+
$_ciphertext_len = strlen($_text);
|
2515 |
+
|
2516 |
+
$_iv = $self->decryptIV;
|
2517 |
+
|
2518 |
+
for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
|
2519 |
+
$in = $_block = substr($_text, $_i, '.$block_size.');
|
2520 |
+
'.$decrypt_block.'
|
2521 |
+
$_plaintext.= $in ^ $_iv;
|
2522 |
+
$_iv = $_block;
|
2523 |
+
}
|
2524 |
+
|
2525 |
+
if ($self->continuousBuffer) {
|
2526 |
+
$self->decryptIV = $_iv;
|
2527 |
+
}
|
2528 |
+
|
2529 |
+
return $self->_unpad($_plaintext);
|
2530 |
+
';
|
2531 |
+
break;
|
2532 |
+
}
|
2533 |
+
|
2534 |
+
// Create the $inline function and return its name as string. Ready to run!
|
2535 |
+
return create_function('$_action, &$self, $_text', $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
|
2536 |
+
}
|
2537 |
+
|
2538 |
+
/**
|
2539 |
+
* Holds the lambda_functions table (classwide)
|
2540 |
+
*
|
2541 |
+
* Each name of the lambda function, created from
|
2542 |
+
* _setupInlineCrypt() && _createInlineCryptFunction()
|
2543 |
+
* is stored, classwide (!), here for reusing.
|
2544 |
+
*
|
2545 |
+
* The string-based index of $function is a classwide
|
2546 |
+
* uniqe value representing, at least, the $mode of
|
2547 |
+
* operation (or more... depends of the optimizing level)
|
2548 |
+
* for which $mode the lambda function was created.
|
2549 |
+
*
|
2550 |
+
* @access private
|
2551 |
+
* @return array &$functions
|
2552 |
+
*/
|
2553 |
+
function &_getLambdaFunctions()
|
2554 |
+
{
|
2555 |
+
static $functions = array();
|
2556 |
+
return $functions;
|
2557 |
+
}
|
2558 |
+
|
2559 |
+
/**
|
2560 |
+
* Generates a digest from $bytes
|
2561 |
+
*
|
2562 |
+
* @see _setupInlineCrypt()
|
2563 |
+
* @access private
|
2564 |
+
* @param $bytes
|
2565 |
+
* @return string
|
2566 |
+
*/
|
2567 |
+
function _hashInlineCryptFunction($bytes)
|
2568 |
+
{
|
2569 |
+
if (!defined('CRYPT_BASE_WHIRLPOOL_AVAILABLE')) {
|
2570 |
+
define('CRYPT_BASE_WHIRLPOOL_AVAILABLE', (bool)(extension_loaded('hash') && in_array('whirlpool', hash_algos())));
|
2571 |
+
}
|
2572 |
+
|
2573 |
+
$result = '';
|
2574 |
+
$hash = $bytes;
|
2575 |
+
|
2576 |
+
switch (true) {
|
2577 |
+
case CRYPT_BASE_WHIRLPOOL_AVAILABLE:
|
2578 |
+
foreach (str_split($bytes, 64) as $t) {
|
2579 |
+
$hash = hash('whirlpool', $hash, true);
|
2580 |
+
$result .= $t ^ $hash;
|
2581 |
+
}
|
2582 |
+
return $result . hash('whirlpool', $hash, true);
|
2583 |
+
default:
|
2584 |
+
$len = strlen($bytes);
|
2585 |
+
for ($i = 0; $i < $len; $i+=20) {
|
2586 |
+
$t = substr($bytes, $i, 20);
|
2587 |
+
$hash = pack('H*', sha1($hash));
|
2588 |
+
$result .= $t ^ $hash;
|
2589 |
+
}
|
2590 |
+
return $result . pack('H*', sha1($hash));
|
2591 |
+
}
|
2592 |
+
}
|
2593 |
+
}
|
lib/phpseclib/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright 2007-2013 TerraFrost and other contributors
|
2 |
+
http://phpseclib.sourceforge.net/
|
3 |
+
|
4 |
+
Permission is hereby granted, free of charge, to any person obtaining
|
5 |
+
a copy of this software and associated documentation files (the
|
6 |
+
"Software"), to deal in the Software without restriction, including
|
7 |
+
without limitation the rights to use, copy, modify, merge, publish,
|
8 |
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9 |
+
permit persons to whom the Software is furnished to do so, subject to
|
10 |
+
the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be
|
13 |
+
included in all copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16 |
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17 |
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18 |
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19 |
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20 |
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21 |
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
lib/phpseclib/Rijndael.php
ADDED
@@ -0,0 +1,1037 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Pure-PHP implementation of Rijndael.
|
5 |
+
*
|
6 |
+
* Uses mcrypt, if available/possible, and an internal implementation, otherwise.
|
7 |
+
*
|
8 |
+
* PHP versions 4 and 5
|
9 |
+
*
|
10 |
+
* If {@link Crypt_Rijndael::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
|
11 |
+
* {@link Crypt_Rijndael::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
12 |
+
* {@link Crypt_Rijndael::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's
|
13 |
+
* 136-bits it'll be null-padded to 192-bits and 192 bits will be the key length until
|
14 |
+
* {@link Crypt_Rijndael::setKey() setKey()} is called, again, at which point, it'll be recalculated.
|
15 |
+
*
|
16 |
+
* Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length. mcrypt, for example,
|
17 |
+
* does not. AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
|
18 |
+
* {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the
|
19 |
+
* algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224. Indeed, 160 and 224
|
20 |
+
* are first defined as valid key / block lengths in
|
21 |
+
* {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}:
|
22 |
+
* Extensions: Other block and Cipher Key lengths.
|
23 |
+
* Note: Use of 160/224-bit Keys must be explicitly set by setKeyLength(160) respectively setKeyLength(224).
|
24 |
+
*
|
25 |
+
* {@internal The variable names are the same as those in
|
26 |
+
* {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}
|
27 |
+
*
|
28 |
+
* Here's a short example of how to use this library:
|
29 |
+
* <code>
|
30 |
+
* <?php
|
31 |
+
* include 'Crypt/Rijndael.php';
|
32 |
+
*
|
33 |
+
* $rijndael = new Crypt_Rijndael();
|
34 |
+
*
|
35 |
+
* $rijndael->setKey('abcdefghijklmnop');
|
36 |
+
*
|
37 |
+
* $size = 10 * 1024;
|
38 |
+
* $plaintext = '';
|
39 |
+
* for ($i = 0; $i < $size; $i++) {
|
40 |
+
* $plaintext.= 'a';
|
41 |
+
* }
|
42 |
+
*
|
43 |
+
* echo $rijndael->decrypt($rijndael->encrypt($plaintext));
|
44 |
+
* ?>
|
45 |
+
* </code>
|
46 |
+
*
|
47 |
+
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
|
48 |
+
* of this software and associated documentation files (the "Software"), to deal
|
49 |
+
* in the Software without restriction, including without limitation the rights
|
50 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
51 |
+
* copies of the Software, and to permit persons to whom the Software is
|
52 |
+
* furnished to do so, subject to the following conditions:
|
53 |
+
*
|
54 |
+
* The above copyright notice and this permission notice shall be included in
|
55 |
+
* all copies or substantial portions of the Software.
|
56 |
+
*
|
57 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
58 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
59 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
60 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
61 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
62 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
63 |
+
* THE SOFTWARE.
|
64 |
+
*
|
65 |
+
* @category Crypt
|
66 |
+
* @package Crypt_Rijndael
|
67 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
68 |
+
* @copyright 2008 Jim Wigginton
|
69 |
+
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
70 |
+
* @link http://phpseclib.sourceforge.net
|
71 |
+
*/
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Include Crypt_Base
|
75 |
+
*
|
76 |
+
* Base cipher class
|
77 |
+
*/
|
78 |
+
if (!class_exists('Crypt_Base')) {
|
79 |
+
include_once 'Base.php';
|
80 |
+
}
|
81 |
+
|
82 |
+
/**#@+
|
83 |
+
* @access public
|
84 |
+
* @see Crypt_Rijndael::encrypt()
|
85 |
+
* @see Crypt_Rijndael::decrypt()
|
86 |
+
*/
|
87 |
+
/**
|
88 |
+
* Encrypt / decrypt using the Counter mode.
|
89 |
+
*
|
90 |
+
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
|
91 |
+
*
|
92 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
|
93 |
+
*/
|
94 |
+
define('CRYPT_RIJNDAEL_MODE_CTR', CRYPT_MODE_CTR);
|
95 |
+
/**
|
96 |
+
* Encrypt / decrypt using the Electronic Code Book mode.
|
97 |
+
*
|
98 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
|
99 |
+
*/
|
100 |
+
define('CRYPT_RIJNDAEL_MODE_ECB', CRYPT_MODE_ECB);
|
101 |
+
/**
|
102 |
+
* Encrypt / decrypt using the Code Book Chaining mode.
|
103 |
+
*
|
104 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
|
105 |
+
*/
|
106 |
+
define('CRYPT_RIJNDAEL_MODE_CBC', CRYPT_MODE_CBC);
|
107 |
+
/**
|
108 |
+
* Encrypt / decrypt using the Cipher Feedback mode.
|
109 |
+
*
|
110 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
111 |
+
*/
|
112 |
+
define('CRYPT_RIJNDAEL_MODE_CFB', CRYPT_MODE_CFB);
|
113 |
+
/**
|
114 |
+
* Encrypt / decrypt using the Cipher Feedback mode.
|
115 |
+
*
|
116 |
+
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
|
117 |
+
*/
|
118 |
+
define('CRYPT_RIJNDAEL_MODE_OFB', CRYPT_MODE_OFB);
|
119 |
+
/**#@-*/
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Pure-PHP implementation of Rijndael.
|
123 |
+
*
|
124 |
+
* @package Crypt_Rijndael
|
125 |
+
* @author Jim Wigginton <terrafrost@php.net>
|
126 |
+
* @access public
|
127 |
+
*/
|
128 |
+
class Crypt_Rijndael extends Crypt_Base
|
129 |
+
{
|
130 |
+
/**
|
131 |
+
* The namespace used by the cipher for its constants.
|
132 |
+
*
|
133 |
+
* @see Crypt_Base::const_namespace
|
134 |
+
* @var string
|
135 |
+
* @access private
|
136 |
+
*/
|
137 |
+
var $const_namespace = 'RIJNDAEL';
|
138 |
+
|
139 |
+
/**
|
140 |
+
* The mcrypt specific name of the cipher
|
141 |
+
*
|
142 |
+
* Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not.
|
143 |
+
* Crypt_Rijndael determines automatically whether mcrypt is useable
|
144 |
+
* or not for the current $block_size/$key_length.
|
145 |
+
* In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly.
|
146 |
+
*
|
147 |
+
* @see Crypt_Base::cipher_name_mcrypt
|
148 |
+
* @see Crypt_Base::engine
|
149 |
+
* @see isValidEngine()
|
150 |
+
* @var string
|
151 |
+
* @access private
|
152 |
+
*/
|
153 |
+
var $cipher_name_mcrypt = 'rijndael-128';
|
154 |
+
|
155 |
+
/**
|
156 |
+
* The default salt used by setPassword()
|
157 |
+
*
|
158 |
+
* @see Crypt_Base::password_default_salt
|
159 |
+
* @see Crypt_Base::setPassword()
|
160 |
+
* @var string
|
161 |
+
* @access private
|
162 |
+
*/
|
163 |
+
var $password_default_salt = 'phpseclib';
|
164 |
+
|
165 |
+
/**
|
166 |
+
* The Key Schedule
|
167 |
+
*
|
168 |
+
* @see _setup()
|
169 |
+
* @var array
|
170 |
+
* @access private
|
171 |
+
*/
|
172 |
+
var $w;
|
173 |
+
|
174 |
+
/**
|
175 |
+
* The Inverse Key Schedule
|
176 |
+
*
|
177 |
+
* @see _setup()
|
178 |
+
* @var array
|
179 |
+
* @access private
|
180 |
+
*/
|
181 |
+
var $dw;
|
182 |
+
|
183 |
+
/**
|
184 |
+
* The Block Length divided by 32
|
185 |
+
*
|
186 |
+
* @see setBlockLength()
|
187 |
+
* @var int
|
188 |
+
* @access private
|
189 |
+
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size
|
190 |
+
* because the encryption / decryption / key schedule creation requires this number and not $block_size. We could
|
191 |
+
* derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
192 |
+
* of that, we'll just precompute it once.
|
193 |
+
*/
|
194 |
+
var $Nb = 4;
|
195 |
+
|
196 |
+
/**
|
197 |
+
* The Key Length (in bytes)
|
198 |
+
*
|
199 |
+
* @see setKeyLength()
|
200 |
+
* @var int
|
201 |
+
* @access private
|
202 |
+
* @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
|
203 |
+
* because the encryption / decryption / key schedule creation requires this number and not $key_length. We could
|
204 |
+
* derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
205 |
+
* of that, we'll just precompute it once.
|
206 |
+
*/
|
207 |
+
var $key_length = 16;
|
208 |
+
|
209 |
+
/**
|
210 |
+
* The Key Length divided by 32
|
211 |
+
*
|
212 |
+
* @see setKeyLength()
|
213 |
+
* @var int
|
214 |
+
* @access private
|
215 |
+
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
|
216 |
+
*/
|
217 |
+
var $Nk = 4;
|
218 |
+
|
219 |
+
/**
|
220 |
+
* The Number of Rounds
|
221 |
+
*
|
222 |
+
* @var int
|
223 |
+
* @access private
|
224 |
+
* @internal The max value is 14, the min value is 10.
|
225 |
+
*/
|
226 |
+
var $Nr;
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Shift offsets
|
230 |
+
*
|
231 |
+
* @var array
|
232 |
+
* @access private
|
233 |
+
*/
|
234 |
+
var $c;
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Holds the last used key- and block_size information
|
238 |
+
*
|
239 |
+
* @var array
|
240 |
+
* @access private
|
241 |
+
*/
|
242 |
+
var $kl;
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Default Constructor.
|
246 |
+
*
|
247 |
+
* Determines whether or not the mcrypt extension should be used.
|
248 |
+
*
|
249 |
+
* $mode could be:
|
250 |
+
*
|
251 |
+
* - CRYPT_RIJNDAEL_MODE_ECB
|
252 |
+
*
|
253 |
+
* - CRYPT_RIJNDAEL_MODE_CBC
|
254 |
+
*
|
255 |
+
* - CRYPT_RIJNDAEL_MODE_CTR
|
256 |
+
*
|
257 |
+
* - CRYPT_RIJNDAEL_MODE_CFB
|
258 |
+
*
|
259 |
+
* - CRYPT_RIJNDAEL_MODE_OFB
|
260 |
+
*
|
261 |
+
* If not explictly set, CRYPT_RIJNDAEL_MODE_CBC will be used.
|
262 |
+
*
|
263 |
+
* @see Crypt_Base::Crypt_Base()
|
264 |
+
* @param int $mode
|
265 |
+
* @access public
|
266 |
+
*/
|
267 |
+
function Crypt_Rijndael($mode = CRYPT_RIJNDAEL_MODE_CBC)
|
268 |
+
{
|
269 |
+
parent::Crypt_Base($mode);
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Sets the key length.
|
274 |
+
*
|
275 |
+
* Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
|
276 |
+
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
|
277 |
+
*
|
278 |
+
* Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined
|
279 |
+
* and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to
|
280 |
+
* 192/256 bits as, for example, mcrypt will do.
|
281 |
+
*
|
282 |
+
* That said, if you want be compatible with other Rijndael and AES implementations,
|
283 |
+
* you should not setKeyLength(160) or setKeyLength(224).
|
284 |
+
*
|
285 |
+
* Additional: In case of 160- and 224-bit keys, phpseclib will/can, for that reason, not use
|
286 |
+
* the mcrypt php extension, even if available.
|
287 |
+
* This results then in slower encryption.
|
288 |
+
*
|
289 |
+
* @access public
|
290 |
+
* @param int $length
|
291 |
+
*/
|
292 |
+
function setKeyLength($length)
|
293 |
+
{
|
294 |
+
switch (true) {
|
295 |
+
case $length <= 128:
|
296 |
+
$this->key_length = 16;
|
297 |
+
break;
|
298 |
+
case $length <= 160:
|
299 |
+
$this->key_length = 20;
|
300 |
+
break;
|
301 |
+
case $length <= 192:
|
302 |
+
$this->key_length = 24;
|
303 |
+
break;
|
304 |
+
case $length <= 224:
|
305 |
+
$this->key_length = 28;
|
306 |
+
break;
|
307 |
+
default:
|
308 |
+
$this->key_length = 32;
|
309 |
+
}
|
310 |
+
|
311 |
+
parent::setKeyLength($length);
|
312 |
+
}
|
313 |
+
|
314 |
+
/**
|
315 |
+
* Sets the block length
|
316 |
+
*
|
317 |
+
* Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
|
318 |
+
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
|
319 |
+
*
|
320 |
+
* @access public
|
321 |
+
* @param int $length
|
322 |
+
*/
|
323 |
+
function setBlockLength($length)
|
324 |
+
{
|
325 |
+
$length >>= 5;
|
326 |
+
if ($length > 8) {
|
327 |
+
$length = 8;
|
328 |
+
} elseif ($length < 4) {
|
329 |
+
$length = 4;
|
330 |
+
}
|
331 |
+
$this->Nb = $length;
|
332 |
+
$this->block_size = $length << 2;
|
333 |
+
$this->changed = true;
|
334 |
+
$this->_setEngine();
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Test for engine validity
|
339 |
+
*
|
340 |
+
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
|
341 |
+
*
|
342 |
+
* @see Crypt_Base::Crypt_Base()
|
343 |
+
* @param int $engine
|
344 |
+
* @access public
|
345 |
+
* @return bool
|
346 |
+
*/
|
347 |
+
function isValidEngine($engine)
|
348 |
+
{
|
349 |
+
switch ($engine) {
|
350 |
+
case CRYPT_ENGINE_OPENSSL:
|
351 |
+
if ($this->block_size != 16) {
|
352 |
+
return false;
|
353 |
+
}
|
354 |
+
$this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb';
|
355 |
+
$this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->_openssl_translate_mode();
|
356 |
+
break;
|
357 |
+
case CRYPT_ENGINE_MCRYPT:
|
358 |
+
$this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3);
|
359 |
+
if ($this->key_length % 8) { // is it a 160/224-bit key?
|
360 |
+
// mcrypt is not usable for them, only for 128/192/256-bit keys
|
361 |
+
return false;
|
362 |
+
}
|
363 |
+
}
|
364 |
+
|
365 |
+
return parent::isValidEngine($engine);
|
366 |
+
}
|
367 |
+
|
368 |
+
/**
|
369 |
+
* Encrypts a block
|
370 |
+
*
|
371 |
+
* @access private
|
372 |
+
* @param string $in
|
373 |
+
* @return string
|
374 |
+
*/
|
375 |
+
function _encryptBlock($in)
|
376 |
+
{
|
377 |
+
static $tables;
|
378 |
+
if (empty($tables)) {
|
379 |
+
$tables = &$this->_getTables();
|
380 |
+
}
|
381 |
+
$t0 = $tables[0];
|
382 |
+
$t1 = $tables[1];
|
383 |
+
$t2 = $tables[2];
|
384 |
+
$t3 = $tables[3];
|
385 |
+
$sbox = $tables[4];
|
386 |
+
|
387 |
+
$state = array();
|
388 |
+
$words = unpack('N*', $in);
|
389 |
+
|
390 |
+
$c = $this->c;
|
391 |
+
$w = $this->w;
|
392 |
+
$Nb = $this->Nb;
|
393 |
+
$Nr = $this->Nr;
|
394 |
+
|
395 |
+
// addRoundKey
|
396 |
+
$wc = $Nb - 1;
|
397 |
+
foreach ($words as $word) {
|
398 |
+
$state[] = $word ^ $w[++$wc];
|
399 |
+
}
|
400 |
+
|
401 |
+
// fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components -
|
402 |
+
// subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding
|
403 |
+
// Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf.
|
404 |
+
// Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization.
|
405 |
+
// Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1],
|
406 |
+
// equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well.
|
407 |
+
|
408 |
+
// [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf
|
409 |
+
$temp = array();
|
410 |
+
for ($round = 1; $round < $Nr; ++$round) {
|
411 |
+
$i = 0; // $c[0] == 0
|
412 |
+
$j = $c[1];
|
413 |
+
$k = $c[2];
|
414 |
+
$l = $c[3];
|
415 |
+
|
416 |
+
while ($i < $Nb) {
|
417 |
+
$temp[$i] = $t0[$state[$i] >> 24 & 0x000000FF] ^
|
418 |
+
$t1[$state[$j] >> 16 & 0x000000FF] ^
|
419 |
+
$t2[$state[$k] >> 8 & 0x000000FF] ^
|
420 |
+
$t3[$state[$l] & 0x000000FF] ^
|
421 |
+
$w[++$wc];
|
422 |
+
++$i;
|
423 |
+
$j = ($j + 1) % $Nb;
|
424 |
+
$k = ($k + 1) % $Nb;
|
425 |
+
$l = ($l + 1) % $Nb;
|
426 |
+
}
|
427 |
+
$state = $temp;
|
428 |
+
}
|
429 |
+
|
430 |
+
// subWord
|
431 |
+
for ($i = 0; $i < $Nb; ++$i) {
|
432 |
+
$state[$i] = $sbox[$state[$i] & 0x000000FF] |
|
433 |
+
($sbox[$state[$i] >> 8 & 0x000000FF] << 8) |
|
434 |
+
($sbox[$state[$i] >> 16 & 0x000000FF] << 16) |
|
435 |
+
($sbox[$state[$i] >> 24 & 0x000000FF] << 24);
|
436 |
+
}
|
437 |
+
|
438 |
+
// shiftRows + addRoundKey
|
439 |
+
$i = 0; // $c[0] == 0
|
440 |
+
$j = $c[1];
|
441 |
+
$k = $c[2];
|
442 |
+
$l = $c[3];
|
443 |
+
while ($i < $Nb) {
|
444 |
+
$temp[$i] = ($state[$i] & 0xFF000000) ^
|
445 |
+
($state[$j] & 0x00FF0000) ^
|
446 |
+
($state[$k] & 0x0000FF00) ^
|
447 |
+
($state[$l] & 0x000000FF) ^
|
448 |
+
$w[$i];
|
449 |
+
++$i;
|
450 |
+
$j = ($j + 1) % $Nb;
|
451 |
+
$k = ($k + 1) % $Nb;
|
452 |
+
$l = ($l + 1) % $Nb;
|
453 |
+
}
|
454 |
+
|
455 |
+
switch ($Nb) {
|
456 |
+
case 8:
|
457 |
+
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
|
458 |
+
case 7:
|
459 |
+
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
|
460 |
+
case 6:
|
461 |
+
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
|
462 |
+
case 5:
|
463 |
+
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
|
464 |
+
default:
|
465 |
+
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
|
466 |
+
}
|
467 |
+
}
|
468 |
+
|
469 |
+
/**
|
470 |
+
* Decrypts a block
|
471 |
+
*
|
472 |
+
* @access private
|
473 |
+
* @param string $in
|
474 |
+
* @return string
|
475 |
+
*/
|
476 |
+
function _decryptBlock($in)
|
477 |
+
{
|
478 |
+
static $invtables;
|
479 |
+
if (empty($invtables)) {
|
480 |
+
$invtables = &$this->_getInvTables();
|
481 |
+
}
|
482 |
+
$dt0 = $invtables[0];
|
483 |
+
$dt1 = $invtables[1];
|
484 |
+
$dt2 = $invtables[2];
|
485 |
+
$dt3 = $invtables[3];
|
486 |
+
$isbox = $invtables[4];
|
487 |
+
|
488 |
+
$state = array();
|
489 |
+
$words = unpack('N*', $in);
|
490 |
+
|
491 |
+
$c = $this->c;
|
492 |
+
$dw = $this->dw;
|
493 |
+
$Nb = $this->Nb;
|
494 |
+
$Nr = $this->Nr;
|
495 |
+
|
496 |
+
// addRoundKey
|
497 |
+
$wc = $Nb - 1;
|
498 |
+
foreach ($words as $word) {
|
499 |
+
$state[] = $word ^ $dw[++$wc];
|
500 |
+
}
|
501 |
+
|
502 |
+
$temp = array();
|
503 |
+
for ($round = $Nr - 1; $round > 0; --$round) {
|
504 |
+
$i = 0; // $c[0] == 0
|
505 |
+
$j = $Nb - $c[1];
|
506 |
+
$k = $Nb - $c[2];
|
507 |
+
$l = $Nb - $c[3];
|
508 |
+
|
509 |
+
while ($i < $Nb) {
|
510 |
+
$temp[$i] = $dt0[$state[$i] >> 24 & 0x000000FF] ^
|
511 |
+
$dt1[$state[$j] >> 16 & 0x000000FF] ^
|
512 |
+
$dt2[$state[$k] >> 8 & 0x000000FF] ^
|
513 |
+
$dt3[$state[$l] & 0x000000FF] ^
|
514 |
+
$dw[++$wc];
|
515 |
+
++$i;
|
516 |
+
$j = ($j + 1) % $Nb;
|
517 |
+
$k = ($k + 1) % $Nb;
|
518 |
+
$l = ($l + 1) % $Nb;
|
519 |
+
}
|
520 |
+
$state = $temp;
|
521 |
+
}
|
522 |
+
|
523 |
+
// invShiftRows + invSubWord + addRoundKey
|
524 |
+
$i = 0; // $c[0] == 0
|
525 |
+
$j = $Nb - $c[1];
|
526 |
+
$k = $Nb - $c[2];
|
527 |
+
$l = $Nb - $c[3];
|
528 |
+
|
529 |
+
while ($i < $Nb) {
|
530 |
+
$word = ($state[$i] & 0xFF000000) |
|
531 |
+
($state[$j] & 0x00FF0000) |
|
532 |
+
($state[$k] & 0x0000FF00) |
|
533 |
+
($state[$l] & 0x000000FF);
|
534 |
+
|
535 |
+
$temp[$i] = $dw[$i] ^ ($isbox[$word & 0x000000FF] |
|
536 |
+
($isbox[$word >> 8 & 0x000000FF] << 8) |
|
537 |
+
($isbox[$word >> 16 & 0x000000FF] << 16) |
|
538 |
+
($isbox[$word >> 24 & 0x000000FF] << 24));
|
539 |
+
++$i;
|
540 |
+
$j = ($j + 1) % $Nb;
|
541 |
+
$k = ($k + 1) % $Nb;
|
542 |
+
$l = ($l + 1) % $Nb;
|
543 |
+
}
|
544 |
+
|
545 |
+
switch ($Nb) {
|
546 |
+
case 8:
|
547 |
+
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
|
548 |
+
case 7:
|
549 |
+
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
|
550 |
+
case 6:
|
551 |
+
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
|
552 |
+
case 5:
|
553 |
+
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
|
554 |
+
default:
|
555 |
+
return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
|
556 |
+
}
|
557 |
+
}
|
558 |
+
|
559 |
+
/**
|
560 |
+
* Setup the key (expansion)
|
561 |
+
*
|
562 |
+
* @see Crypt_Base::_setupKey()
|
563 |
+
* @access private
|
564 |
+
*/
|
565 |
+
function _setupKey()
|
566 |
+
{
|
567 |
+
// Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.
|
568 |
+
// See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse
|
569 |
+
static $rcon = array(0,
|
570 |
+
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
|
571 |
+
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
|
572 |
+
0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
|
573 |
+
0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
|
574 |
+
0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
|
575 |
+
0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
|
576 |
+
);
|
577 |
+
|
578 |
+
if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) {
|
579 |
+
// already expanded
|
580 |
+
return;
|
581 |
+
}
|
582 |
+
$this->kl = array('key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size);
|
583 |
+
|
584 |
+
$this->Nk = $this->key_length >> 2;
|
585 |
+
// see Rijndael-ammended.pdf#page=44
|
586 |
+
$this->Nr = max($this->Nk, $this->Nb) + 6;
|
587 |
+
|
588 |
+
// shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44,
|
589 |
+
// "Table 8: Shift offsets in Shiftrow for the alternative block lengths"
|
590 |
+
// shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14,
|
591 |
+
// "Table 2: Shift offsets for different block lengths"
|
592 |
+
switch ($this->Nb) {
|
593 |
+
case 4:
|
594 |
+
case 5:
|
595 |
+
case 6:
|
596 |
+
$this->c = array(0, 1, 2, 3);
|
597 |
+
break;
|
598 |
+
case 7:
|
599 |
+
$this->c = array(0, 1, 2, 4);
|
600 |
+
break;
|
601 |
+
case 8:
|
602 |
+
$this->c = array(0, 1, 3, 4);
|
603 |
+
}
|
604 |
+
|
605 |
+
$w = array_values(unpack('N*words', $this->key));
|
606 |
+
|
607 |
+
$length = $this->Nb * ($this->Nr + 1);
|
608 |
+
for ($i = $this->Nk; $i < $length; $i++) {
|
609 |
+
$temp = $w[$i - 1];
|
610 |
+
if ($i % $this->Nk == 0) {
|
611 |
+
// according to <http://php.net/language.types.integer>, "the size of an integer is platform-dependent".
|
612 |
+
// on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
|
613 |
+
// 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
|
614 |
+
// with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
|
615 |
+
$temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
|
616 |
+
$temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
|
617 |
+
} elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
|
618 |
+
$temp = $this->_subWord($temp);
|
619 |
+
}
|
620 |
+
$w[$i] = $w[$i - $this->Nk] ^ $temp;
|
621 |
+
}
|
622 |
+
|
623 |
+
// convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns
|
624 |
+
// and generate the inverse key schedule. more specifically,
|
625 |
+
// according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=23> (section 5.3.3),
|
626 |
+
// "The key expansion for the Inverse Cipher is defined as follows:
|
627 |
+
// 1. Apply the Key Expansion.
|
628 |
+
// 2. Apply InvMixColumn to all Round Keys except the first and the last one."
|
629 |
+
// also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"
|
630 |
+
list($dt0, $dt1, $dt2, $dt3) = $this->_getInvTables();
|
631 |
+
$temp = $this->w = $this->dw = array();
|
632 |
+
for ($i = $row = $col = 0; $i < $length; $i++, $col++) {
|
633 |
+
if ($col == $this->Nb) {
|
634 |
+
if ($row == 0) {
|
635 |
+
$this->dw[0] = $this->w[0];
|
636 |
+
} else {
|
637 |
+
// subWord + invMixColumn + invSubWord = invMixColumn
|
638 |
+
$j = 0;
|
639 |
+
while ($j < $this->Nb) {
|
640 |
+
$dw = $this->_subWord($this->w[$row][$j]);
|
641 |
+
$temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^
|
642 |
+
$dt1[$dw >> 16 & 0x000000FF] ^
|
643 |
+
$dt2[$dw >> 8 & 0x000000FF] ^
|
644 |
+
$dt3[$dw & 0x000000FF];
|
645 |
+
$j++;
|
646 |
+
}
|
647 |
+
$this->dw[$row] = $temp;
|
648 |
+
}
|
649 |
+
|
650 |
+
$col = 0;
|
651 |
+
$row++;
|
652 |
+
}
|
653 |
+
$this->w[$row][$col] = $w[$i];
|
654 |
+
}
|
655 |
+
|
656 |
+
$this->dw[$row] = $this->w[$row];
|
657 |
+
|
658 |
+
// Converting to 1-dim key arrays (both ascending)
|
659 |
+
$this->dw = array_reverse($this->dw);
|
660 |
+
$w = array_pop($this->w);
|
661 |
+
$dw = array_pop($this->dw);
|
662 |
+
foreach ($this->w as $r => $wr) {
|
663 |
+
foreach ($wr as $c => $wc) {
|
664 |
+
$w[] = $wc;
|
665 |
+
$dw[] = $this->dw[$r][$c];
|
666 |
+
}
|
667 |
+
}
|
668 |
+
$this->w = $w;
|
669 |
+
$this->dw = $dw;
|
670 |
+
}
|
671 |
+
|
672 |
+
/**
|
673 |
+
* Performs S-Box substitutions
|
674 |
+
*
|
675 |
+
* @access private
|
676 |
+
* @param int $word
|
677 |
+
*/
|
678 |
+
function _subWord($word)
|
679 |
+
{
|
680 |
+
static $sbox;
|
681 |
+
if (empty($sbox)) {
|
682 |
+
list(, , , , $sbox) = $this->_getTables();
|
683 |
+
}
|
684 |
+
|
685 |
+
return $sbox[$word & 0x000000FF] |
|
686 |
+
($sbox[$word >> 8 & 0x000000FF] << 8) |
|
687 |
+
($sbox[$word >> 16 & 0x000000FF] << 16) |
|
688 |
+
($sbox[$word >> 24 & 0x000000FF] << 24);
|
689 |
+
}
|
690 |
+
|
691 |
+
/**
|
692 |
+
* Provides the mixColumns and sboxes tables
|
693 |
+
*
|
694 |
+
* @see Crypt_Rijndael:_encryptBlock()
|
695 |
+
* @see Crypt_Rijndael:_setupInlineCrypt()
|
696 |
+
* @see Crypt_Rijndael:_subWord()
|
697 |
+
* @access private
|
698 |
+
* @return array &$tables
|
699 |
+
*/
|
700 |
+
function &_getTables()
|
701 |
+
{
|
702 |
+
static $tables;
|
703 |
+
if (empty($tables)) {
|
704 |
+
// according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
|
705 |
+
// precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
|
706 |
+
// those are the names we'll use.
|
707 |
+
$t3 = array_map('intval', array(
|
708 |
+
// with array_map('intval', ...) we ensure we have only int's and not
|
709 |
+
// some slower floats converted by php automatically on high values
|
710 |
+
0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
|
711 |
+
0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
|
712 |
+
0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
|
713 |
+
0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
|
714 |
+
0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
|
715 |
+
0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
|
716 |
+
0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
|
717 |
+
0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
|
718 |
+
0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
|
719 |
+
0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
|
720 |
+
0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
|
721 |
+
0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
|
722 |
+
0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
|
723 |
+
0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
|
724 |
+
0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
|
725 |
+
0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
|
726 |
+
0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
|
727 |
+
0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
|
728 |
+
0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
|
729 |
+
0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
|
730 |
+
0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
|
731 |
+
0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
|
732 |
+
0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
|
733 |
+
0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
|
734 |
+
0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
|
735 |
+
0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
|
736 |
+
0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
|
737 |
+
0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
|
738 |
+
0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
|
739 |
+
0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
|
740 |
+
0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
|
741 |
+
0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
|
742 |
+
));
|
743 |
+
|
744 |
+
foreach ($t3 as $t3i) {
|
745 |
+
$t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >> 8) & 0x00FFFFFF);
|
746 |
+
$t1[] = (($t3i << 16) & 0xFFFF0000) | (($t3i >> 16) & 0x0000FFFF);
|
747 |
+
$t2[] = (($t3i << 8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF);
|
748 |
+
}
|
749 |
+
|
750 |
+
$tables = array(
|
751 |
+
// The Precomputed mixColumns tables t0 - t3
|
752 |
+
$t0,
|
753 |
+
$t1,
|
754 |
+
$t2,
|
755 |
+
$t3,
|
756 |
+
// The SubByte S-Box
|
757 |
+
array(
|
758 |
+
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
759 |
+
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
760 |
+
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
761 |
+
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
762 |
+
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
763 |
+
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
764 |
+
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
765 |
+
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
766 |
+
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
767 |
+
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
768 |
+
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
769 |
+
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
770 |
+
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
771 |
+
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
772 |
+
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
773 |
+
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
|
774 |
+
)
|
775 |
+
);
|
776 |
+
}
|
777 |
+
return $tables;
|
778 |
+
}
|
779 |
+
|
780 |
+
/**
|
781 |
+
* Provides the inverse mixColumns and inverse sboxes tables
|
782 |
+
*
|
783 |
+
* @see Crypt_Rijndael:_decryptBlock()
|
784 |
+
* @see Crypt_Rijndael:_setupInlineCrypt()
|
785 |
+
* @see Crypt_Rijndael:_setupKey()
|
786 |
+
* @access private
|
787 |
+
* @return array &$tables
|
788 |
+
*/
|
789 |
+
function &_getInvTables()
|
790 |
+
{
|
791 |
+
static $tables;
|
792 |
+
if (empty($tables)) {
|
793 |
+
$dt3 = array_map('intval', array(
|
794 |
+
0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
|
795 |
+
0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
|
796 |
+
0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
|
797 |
+
0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
|
798 |
+
0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
|
799 |
+
0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
|
800 |
+
0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
|
801 |
+
0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
|
802 |
+
0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
|
803 |
+
0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
|
804 |
+
0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
|
805 |
+
0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
|
806 |
+
0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
|
807 |
+
0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
|
808 |
+
0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
|
809 |
+
0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
|
810 |
+
0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
|
811 |
+
0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
|
812 |
+
0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
|
813 |
+
0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
|
814 |
+
0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
|
815 |
+
0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
|
816 |
+
0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
|
817 |
+
0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
|
818 |
+
0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
|
819 |
+
0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
|
820 |
+
0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
|
821 |
+
0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
|
822 |
+
0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
|
823 |
+
0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
|
824 |
+
0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
|
825 |
+
0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
|
826 |
+
));
|
827 |
+
|
828 |
+
foreach ($dt3 as $dt3i) {
|
829 |
+
$dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF);
|
830 |
+
$dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF);
|
831 |
+
$dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF);
|
832 |
+
};
|
833 |
+
|
834 |
+
$tables = array(
|
835 |
+
// The Precomputed inverse mixColumns tables dt0 - dt3
|
836 |
+
$dt0,
|
837 |
+
$dt1,
|
838 |
+
$dt2,
|
839 |
+
$dt3,
|
840 |
+
// The inverse SubByte S-Box
|
841 |
+
array(
|
842 |
+
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
|
843 |
+
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
|
844 |
+
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
|
845 |
+
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
|
846 |
+
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
|
847 |
+
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
|
848 |
+
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
|
849 |
+
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
|
850 |
+
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
|
851 |
+
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
|
852 |
+
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
|
853 |
+
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
|
854 |
+
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
|
855 |
+
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
|
856 |
+
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
|
857 |
+
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
|
858 |
+
)
|
859 |
+
);
|
860 |
+
}
|
861 |
+
return $tables;
|
862 |
+
}
|
863 |
+
|
864 |
+
/**
|
865 |
+
* Setup the performance-optimized function for de/encrypt()
|
866 |
+
*
|
867 |
+
* @see Crypt_Base::_setupInlineCrypt()
|
868 |
+
* @access private
|
869 |
+
*/
|
870 |
+
function _setupInlineCrypt()
|
871 |
+
{
|
872 |
+
// Note: _setupInlineCrypt() will be called only if $this->changed === true
|
873 |
+
// So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt().
|
874 |
+
// However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible.
|
875 |
+
|
876 |
+
$lambda_functions =& Crypt_Rijndael::_getLambdaFunctions();
|
877 |
+
|
878 |
+
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
879 |
+
// (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit)
|
880 |
+
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
|
881 |
+
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
882 |
+
|
883 |
+
// Generation of a uniqe hash for our generated code
|
884 |
+
$code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}";
|
885 |
+
if ($gen_hi_opt_code) {
|
886 |
+
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
887 |
+
}
|
888 |
+
|
889 |
+
if (!isset($lambda_functions[$code_hash])) {
|
890 |
+
switch (true) {
|
891 |
+
case $gen_hi_opt_code:
|
892 |
+
// The hi-optimized $lambda_functions will use the key-words hardcoded for better performance.
|
893 |
+
$w = $this->w;
|
894 |
+
$dw = $this->dw;
|
895 |
+
$init_encrypt = '';
|
896 |
+
$init_decrypt = '';
|
897 |
+
break;
|
898 |
+
default:
|
899 |
+
for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) {
|
900 |
+
$w[] = '$w[' . $i . ']';
|
901 |
+
$dw[] = '$dw[' . $i . ']';
|
902 |
+
}
|
903 |
+
$init_encrypt = '$w = $self->w;';
|
904 |
+
$init_decrypt = '$dw = $self->dw;';
|
905 |
+
}
|
906 |
+
|
907 |
+
$Nr = $this->Nr;
|
908 |
+
$Nb = $this->Nb;
|
909 |
+
$c = $this->c;
|
910 |
+
|
911 |
+
// Generating encrypt code:
|
912 |
+
$init_encrypt.= '
|
913 |
+
static $tables;
|
914 |
+
if (empty($tables)) {
|
915 |
+
$tables = &$self->_getTables();
|
916 |
+
}
|
917 |
+
$t0 = $tables[0];
|
918 |
+
$t1 = $tables[1];
|
919 |
+
$t2 = $tables[2];
|
920 |
+
$t3 = $tables[3];
|
921 |
+
$sbox = $tables[4];
|
922 |
+
';
|
923 |
+
|
924 |
+
$s = 'e';
|
925 |
+
$e = 's';
|
926 |
+
$wc = $Nb - 1;
|
927 |
+
|
928 |
+
// Preround: addRoundKey
|
929 |
+
$encrypt_block = '$in = unpack("N*", $in);'."\n";
|
930 |
+
for ($i = 0; $i < $Nb; ++$i) {
|
931 |
+
$encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n";
|
932 |
+
}
|
933 |
+
|
934 |
+
// Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
|
935 |
+
for ($round = 1; $round < $Nr; ++$round) {
|
936 |
+
list($s, $e) = array($e, $s);
|
937 |
+
for ($i = 0; $i < $Nb; ++$i) {
|
938 |
+
$encrypt_block.=
|
939 |
+
'$'.$e.$i.' =
|
940 |
+
$t0[($'.$s.$i .' >> 24) & 0xff] ^
|
941 |
+
$t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^
|
942 |
+
$t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^
|
943 |
+
$t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^
|
944 |
+
'.$w[++$wc].";\n";
|
945 |
+
}
|
946 |
+
}
|
947 |
+
|
948 |
+
// Finalround: subWord + shiftRows + addRoundKey
|
949 |
+
for ($i = 0; $i < $Nb; ++$i) {
|
950 |
+
$encrypt_block.=
|
951 |
+
'$'.$e.$i.' =
|
952 |
+
$sbox[ $'.$e.$i.' & 0xff] |
|
953 |
+
($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
|
954 |
+
($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
|
955 |
+
($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
|
956 |
+
}
|
957 |
+
$encrypt_block .= '$in = pack("N*"'."\n";
|
958 |
+
for ($i = 0; $i < $Nb; ++$i) {
|
959 |
+
$encrypt_block.= ',
|
960 |
+
($'.$e.$i .' & '.((int)0xFF000000).') ^
|
961 |
+
($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^
|
962 |
+
($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^
|
963 |
+
($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^
|
964 |
+
'.$w[$i]."\n";
|
965 |
+
}
|
966 |
+
$encrypt_block .= ');';
|
967 |
+
|
968 |
+
// Generating decrypt code:
|
969 |
+
$init_decrypt.= '
|
970 |
+
static $invtables;
|
971 |
+
if (empty($invtables)) {
|
972 |
+
$invtables = &$self->_getInvTables();
|
973 |
+
}
|
974 |
+
$dt0 = $invtables[0];
|
975 |
+
$dt1 = $invtables[1];
|
976 |
+
$dt2 = $invtables[2];
|
977 |
+
$dt3 = $invtables[3];
|
978 |
+
$isbox = $invtables[4];
|
979 |
+
';
|
980 |
+
|
981 |
+
$s = 'e';
|
982 |
+
$e = 's';
|
983 |
+
$wc = $Nb - 1;
|
984 |
+
|
985 |
+
// Preround: addRoundKey
|
986 |
+
$decrypt_block = '$in = unpack("N*", $in);'."\n";
|
987 |
+
for ($i = 0; $i < $Nb; ++$i) {
|
988 |
+
$decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n";
|
989 |
+
}
|
990 |
+
|
991 |
+
// Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
|
992 |
+
for ($round = 1; $round < $Nr; ++$round) {
|
993 |
+
list($s, $e) = array($e, $s);
|
994 |
+
for ($i = 0; $i < $Nb; ++$i) {
|
995 |
+
$decrypt_block.=
|
996 |
+
'$'.$e.$i.' =
|
997 |
+
$dt0[($'.$s.$i .' >> 24) & 0xff] ^
|
998 |
+
$dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^
|
999 |
+
$dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^
|
1000 |
+
$dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^
|
1001 |
+
'.$dw[++$wc].";\n";
|
1002 |
+
}
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
// Finalround: subWord + shiftRows + addRoundKey
|
1006 |
+
for ($i = 0; $i < $Nb; ++$i) {
|
1007 |
+
$decrypt_block.=
|
1008 |
+
'$'.$e.$i.' =
|
1009 |
+
$isbox[ $'.$e.$i.' & 0xff] |
|
1010 |
+
($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
|
1011 |
+
($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
|
1012 |
+
($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
|
1013 |
+
}
|
1014 |
+
$decrypt_block .= '$in = pack("N*"'."\n";
|
1015 |
+
for ($i = 0; $i < $Nb; ++$i) {
|
1016 |
+
$decrypt_block.= ',
|
1017 |
+
($'.$e.$i. ' & '.((int)0xFF000000).') ^
|
1018 |
+
($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^
|
1019 |
+
($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^
|
1020 |
+
($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^
|
1021 |
+
'.$dw[$i]."\n";
|
1022 |
+
}
|
1023 |
+
$decrypt_block .= ');';
|
1024 |
+
|
1025 |
+
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
|
1026 |
+
array(
|
1027 |
+
'init_crypt' => '',
|
1028 |
+
'init_encrypt' => $init_encrypt,
|
1029 |
+
'init_decrypt' => $init_decrypt,
|
1030 |
+
'encrypt_block' => $encrypt_block,
|
1031 |
+
'decrypt_block' => $decrypt_block
|
1032 |
+
)
|
1033 |
+
);
|
1034 |
+
}
|
1035 |
+
$this->inline_crypt = $lambda_functions[$code_hash];
|
1036 |
+
}
|
1037 |
+
}
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: ecwid
|
|
3 |
Tags: ecwid, shopping cart, ecommerce, wordpress ecommerce, wp e-commerce, paypal, e-commerce, online store, store, shop, cart, online shop, shopping, digital goods, downloadable products, product catalog, ecomerce, products, facebook, f-commerce
|
4 |
Requires at least: 2.8
|
5 |
Tested up to: 4.3
|
6 |
-
Stable tag: 3.4.
|
7 |
|
8 |
Ecwid is a full-featured shopping cart that can be added to any Wordpress site in less than 5 minutes. Start using Ecwid for free today.
|
9 |
|
@@ -107,6 +107,14 @@ http://codex.wordpress.org/Managing_Plugins#Installing_Plugins
|
|
107 |
* [Ecwid site](http://www.ecwid.com/?source=wporg-plugin-site "Ecwid Site")
|
108 |
|
109 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
= 3.4.2 =
|
111 |
- Fixed option to enable the new categories widget released in the v.3.4 .
|
112 |
|
3 |
Tags: ecwid, shopping cart, ecommerce, wordpress ecommerce, wp e-commerce, paypal, e-commerce, online store, store, shop, cart, online shop, shopping, digital goods, downloadable products, product catalog, ecomerce, products, facebook, f-commerce
|
4 |
Requires at least: 2.8
|
5 |
Tested up to: 4.3
|
6 |
+
Stable tag: 3.4.4
|
7 |
|
8 |
Ecwid is a full-featured shopping cart that can be added to any Wordpress site in less than 5 minutes. Start using Ecwid for free today.
|
9 |
|
107 |
* [Ecwid site](http://www.ecwid.com/?source=wporg-plugin-site "Ecwid Site")
|
108 |
|
109 |
== Changelog ==
|
110 |
+
= 3.4.4 =
|
111 |
+
- **Added compatibility with the "Add Meta Tags" plugin.** The "Add Meta Tags" plugin is a popular tool to set SEO meta tags on site pages. Previously it rewrote the titles and description that Ecwid generated for search engines on your site. It's now fixed so if you use the plugin, everything should work fine and Google will index your products pages properly.
|
112 |
+
- **Fixed a problem in the recently viewed products widget caused by Autoptimize plugin.** Previously, if Autoptimize plugin is used on the site, the recently viewed products widget reset the displayed products when page reloads. We fixed that.
|
113 |
+
- **A few internal improvements** to make the plugin more stable and ready for the upcoming cool features. Stay tuned! More updates are coming.
|
114 |
+
|
115 |
+
= 3.4.3 =
|
116 |
+
- Updated Italian and Turkish translations.
|
117 |
+
|
118 |
= 3.4.2 =
|
119 |
- Fixed option to enable the new categories widget released in the v.3.4 .
|
120 |
|
templates/connect.php
CHANGED
@@ -48,5 +48,5 @@
|
|
48 |
</a>
|
49 |
</div>
|
50 |
</div>
|
51 |
-
<p><?php echo sprintf(__('Questions?
|
52 |
</div>
|
48 |
</a>
|
49 |
</div>
|
50 |
</div>
|
51 |
+
<p><?php echo sprintf(__('Questions? <a %s>Read FAQ</a> or contact support at <a %s>wordpress@ecwid.com</a>', 'ecwid-shopping-cart'), 'target="_blank" href="https://help.ecwid.com/customer/portal/articles/1085017-wordpress-downloadable#FAQ"', 'href="mailto:wordpress@ecwid.com"'); ?></p>
|
52 |
</div>
|
templates/dashboard.php
CHANGED
@@ -54,5 +54,5 @@
|
|
54 |
</div>
|
55 |
|
56 |
</div>
|
57 |
-
<p><?php echo sprintf(__('Questions?
|
58 |
</div>
|
54 |
</div>
|
55 |
|
56 |
</div>
|
57 |
+
<p><?php echo sprintf(__('Questions? <a %s>Read FAQ</a> or contact support at <a %s>wordpress@ecwid.com</a>', 'ecwid-shopping-cart'), 'target="_blank" href="https://help.ecwid.com/customer/portal/articles/1085017-wordpress-downloadable#FAQ"', 'href="mailto:wordpress@ecwid.com"'); ?></p>
|
58 |
</div>
|
templates/reconnect.php
CHANGED
@@ -1,31 +1,51 @@
|
|
1 |
-
<div class="wrap ecwid-admin ecwid-connect">
|
2 |
<div class="box">
|
3 |
-
<
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
</
|
8 |
<div class="greeting-image">
|
9 |
<img src="<?php echo(esc_attr(ECWID_PLUGIN_URL)); ?>/images/store_inprogress.png" width="142" />
|
10 |
</div>
|
11 |
|
12 |
<div class="greeting-message mobile-br">
|
13 |
-
<?php _e( '
|
14 |
</div>
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
<div class="connect-button">
|
17 |
-
<a href="
|
18 |
</div>
|
19 |
|
20 |
-
|
21 |
-
<?php _e( 'New features available, reconnect to be in touch with our updates', 'ecwid-shopping-cart' ); ?>
|
22 |
-
</div>
|
23 |
|
24 |
-
|
25 |
-
<
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
</div>
|
30 |
-
<p><?php
|
31 |
</div>
|
1 |
+
<div class="wrap ecwid-admin ecwid-connect ecwid-reconnect">
|
2 |
<div class="box">
|
3 |
+
<div class="head"><?php ecwid_embed_svg('ecwid_logo_symbol_RGB');?>
|
4 |
+
<h3>
|
5 |
+
<?php _e( 'Ecwid Shopping Cart', 'ecwid-shopping-cart' ); ?>
|
6 |
+
</h3>
|
7 |
+
</div>
|
8 |
<div class="greeting-image">
|
9 |
<img src="<?php echo(esc_attr(ECWID_PLUGIN_URL)); ?>/images/store_inprogress.png" width="142" />
|
10 |
</div>
|
11 |
|
12 |
<div class="greeting-message mobile-br">
|
13 |
+
<?php _e( 'Connect your store<br /> to this WordPress site', 'ecwid-shopping-cart' ); ?>
|
14 |
</div>
|
15 |
|
16 |
+
<?php if ($ecwid_oauth->get_reconnect_message()): ?>
|
17 |
+
<div class="note reconnect-message">
|
18 |
+
<?php echo $ecwid_oauth->get_reconnect_message(); ?>
|
19 |
+
</div>
|
20 |
+
<?php endif; ?>
|
21 |
+
|
22 |
<div class="connect-button">
|
23 |
+
<a href="admin-post.php?action=ecwid_connect&reconnect"><?php _e( 'Connect Ecwid store', 'ecwid-shopping-cart' ); ?></a>
|
24 |
</div>
|
25 |
|
26 |
+
<?php if ($connection_error && $ecwid_oauth->get_error() == 'cancelled'): ?>
|
|
|
|
|
27 |
|
28 |
+
|
29 |
+
<div class="note auth-error">
|
30 |
+
<span>
|
31 |
+
<?php _e( 'Connection error - after clicking button you need to login and accept permissions to use our plugin. Please, try again.', 'ecwid-shopping-cart' ); ?>
|
32 |
+
</span>
|
33 |
+
</div>
|
34 |
+
|
35 |
+
<?php elseif ($connection_error && $ecwid_oauth->get_error() == 'other'): ?>
|
36 |
+
|
37 |
+
<div class="note auth-error">
|
38 |
+
<span>
|
39 |
+
<?php _e( 'Looks like your site does not support remote POST requests that are required for Ecwid API to work. Please, contact your hosting provider to enable cURL.', 'ecwid-shopping-cart' ); ?>
|
40 |
+
</span>
|
41 |
+
</div>
|
42 |
+
|
43 |
+
<?php else: ?>
|
44 |
+
|
45 |
+
<div class="note">
|
46 |
+
<?php _e( 'After clicking button you need to login and accept permissions to use our plugin', 'ecwid-shopping-cart' ); ?>
|
47 |
+
</div>
|
48 |
+
<?php endif; ?>
|
49 |
</div>
|
50 |
+
<p><?php echo sprintf(__('Questions? <a %s>Read FAQ</a> or contact support at <a %s>wordpress@ecwid.com</a>', 'ecwid-shopping-cart'), 'target="_blank" href="https://help.ecwid.com/customer/portal/articles/1085017-wordpress-downloadable#FAQ"', 'href="mailto:wordpress@ecwid.com"'); ?></p>
|
51 |
</div>
|