Skip to content

Commit

Permalink
CRM-21085 Replace mcrypt functions where possible with openssl versio…
Browse files Browse the repository at this point in the history
…ns and add in upgrade step to convert
  • Loading branch information
seamuslee001 committed Aug 21, 2017
1 parent 74c7dfd commit c472c0c
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 29 deletions.
18 changes: 18 additions & 0 deletions CRM/Upgrade/Incremental/php/FourSeven.php
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ public function upgrade_4_7_25($rev) {
'civicrm_menu', 'module_data', "text COMMENT 'All other menu metadata not stored in other fields'");
$this->addTask('CRM-21052 - Determine activity revision policy', 'pickActivityRevisionPolicy');
$this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
$this->addTask('CRM-21085 - Convert passwords from mcrypt to openssl', 'updateEncryptionMethod');
}


Expand Down Expand Up @@ -1217,4 +1218,21 @@ protected function checkImageUploadDir() {
return $config->imageUploadDir && $config->imageUploadURL && $check->isDirAccessible($config->imageUploadDir, $config->imageUploadURL);
}

public static function updateEncryptionMethod() {
$mailingInfo = CRM_Core_DAO::executeQuery("SELECT domain_id, value FROM civicrm_setting WHERE name = 'mailing_backend'")->fetchAll();
foreach ($mailingInfo as $mailing) {
$values = unserialize($mailing['info']);
if (!empty($values['smtpPassword'])) {
$password = CRM_Utils_Crypt::decrypt($values, TRUE);
$values['smtpPassword'] = CRM_Utils_Crypt::encrypt($password);
}
$values = serialize($values);
CRM_Core_DAO::executeQuery("UPDATE civicrm_setting set value = %1 WHERE domain_id = %2 AND name = 'mailing_backend'", array(
1 => array($values, 'String'),
2 => array($mailing['domain_id'], 'Positive'),
));
}
return TRUE;
}

}
60 changes: 31 additions & 29 deletions CRM/Utils/Crypt.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,13 @@ public static function encrypt($string) {
if (empty($string)) {
return $string;
}

if (function_exists('mcrypt_module_open') &&
defined('CIVICRM_SITE_KEY')
) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_ECB, '');
// ECB mode - iv not needed - CRM-8198
$iv = '00000000000000000000000000000000';
$ks = mcrypt_enc_get_key_size($td);
$key = substr(sha1(CIVICRM_SITE_KEY), 0, $ks);

mcrypt_generic_init($td, $key, $iv);
$string = mcrypt_generic($td, $string);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
if (defined('CIVICRM_SITE_KEY') && function_exists('openssl_encrypt')) {
$raw = defined('OPENSSL_RAW_DATA') ? OPENSSL_RAW_DATA : TRUE;
$key = openssl_digest(CIVICRM_SITE_KEY, 'sha256');
$method = 'AES-256-ECB';
$ivSize = 0;
$iv = substr($key, 0, $ivSize);
$string = openssl_encrypt($string, $method, $key, $raw, $iv);
}
return base64_encode($string);
}
Expand All @@ -77,11 +70,13 @@ public static function encrypt($string) {
*
* @param string $string
* Ciphertext to be decrypted.
* @param bool $useMcrypt
* Should we use the mcrypt methods of decryption
* @return string
* Plaintext, or base64-decoded ciphertext if encryption is disabled or
* unavailable.
*/
public static function decrypt($string) {
public static function decrypt($string, $useMcrypt = FALSE) {
if (empty($string)) {
return $string;
}
Expand All @@ -90,22 +85,29 @@ public static function decrypt($string) {
if (empty($string)) {
return $string;
}
if (defined('CIVICRM_SITE_KEY')) {
if (!$useMcrypt && function_exists('openssl_decrypt')) {
$raw = defined('OPENSSL_RAW_DATA') ? OPENSSL_RAW_DATA : TRUE;
$key = openssl_digest(CIVICRM_SITE_KEY, 'sha256');
$method = 'AES-256-ECB';
$ivSize = 0;
$iv = substr($string, 0, $ivSize);
$data = substr($string, $ivSize);
$string = openssl_decrypt($data, $method, $key, $raw, $iv);
}
elseif (function_exists('mcrypt_module_open')) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_ECB, '');
// ECB mode - iv not needed - CRM-8198
$iv = '00000000000000000000000000000000';
$ks = mcrypt_enc_get_key_size($td);
$key = substr(sha1(CIVICRM_SITE_KEY), 0, $ks);

if (function_exists('mcrypt_module_open') &&
defined('CIVICRM_SITE_KEY')
) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_ECB, '');
// ECB mode - iv not needed - CRM-8198
$iv = '00000000000000000000000000000000';
$ks = mcrypt_enc_get_key_size($td);
$key = substr(sha1(CIVICRM_SITE_KEY), 0, $ks);

mcrypt_generic_init($td, $key, $iv);
$string = rtrim(mdecrypt_generic($td, $string));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
mcrypt_generic_init($td, $key, $iv);
$string = rtrim(mdecrypt_generic($td, $string));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
}
}

return $string;
}

Expand Down
37 changes: 37 additions & 0 deletions tests/phpunit/CRM/Utils/CryptTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/**
* Class CRM_Utils_CryptTest
* @group headless
*/
class CRM_Utils_CryptTest extends CiviUnitTestCase {

public function testMcryptToOpenSSL() {
$testString = 'This is a test encrpytion';
if (function_exists('mcrypt_module_open') && defined('CIVICRM_SITE_KEY')) {
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_ECB, '');
// ECB mode - iv not needed - CRM-8198
$iv = '00000000000000000000000000000000';
$ks = mcrypt_enc_get_key_size($td);
$key = substr(sha1(CIVICRM_SITE_KEY), 0, $ks);
mcrypt_generic_init($td, $key, $iv);
$string = mcrypt_generic($td, $testString);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$mcryptString = base64_encode($string);
if (function_exists('openssl_encrypt')) {
$decrptyedMcryptString = CRM_Utils_Crypt::decrypt($mcryptString, TRUE);
$opensslEncrpyt = CRM_Utils_Crypt::encrypt($decrptyedMcryptString);
$opensslDecryted = CRM_Utils_Crypt::decrypt($opensslEncrpyt);
$this->assertEquals($testString, $opensslDecryted);
}
else {
$this->fail('OpenSSL module not avaliable');
}
}
else {
$this->fail('mcrypt is not enabled or site_key is not defined');
}
}

}

0 comments on commit c472c0c

Please sign in to comment.