| @@ -86,63 +86,12 @@ | ||
| 86 | 86 | |
| 87 | 87 | return $code; |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | - // Port over keys that were encrypted with mcrypt and its non-compliant padding scheme, so that if the site is ever migrated to a server without mcrypt, they can still be decrypted | |
| 91 | - public function potentially_port_private_keys() { | |
| 92 | 90 | |
| 93 | - $simba_tfa_priv_key_format = get_site_option('simba_tfa_priv_key_format', false); | |
| 94 | - | |
| 95 | - $attempts = 0; | |
| 96 | - $successes = 0; | |
| 97 | - | |
| 98 | - if ($simba_tfa_priv_key_format < 1 && function_exists('openssl_encrypt')) { | |
| 99 | - | |
| 100 | - error_log("TFA: Beginning attempt to port private key encryption over to openssl"); | |
| 101 | - global $wpdb; | |
| 102 | - $sql = "SELECT user_id, meta_value FROM ".$wpdb->usermeta." WHERE meta_key = 'tfa_priv_key_64'"; | |
| 103 | - | |
| 104 | - $user_results = $wpdb->get_results($sql); | |
| 105 | - | |
| 106 | - foreach ($user_results as $u) { | |
| 107 | - $dec_openssl = $this->decryptString($u->meta_value, $u->user_id, true); | |
| 108 | - | |
| 109 | - $ported = false; | |
| 110 | - if ('' == $dec_openssl) { | |
| 111 | - | |
| 112 | - $attempts++; | |
| 113 | - | |
| 114 | - $dec_default = $this->decryptString($u->meta_value, $u->user_id); | |
| 115 | - | |
| 116 | - if ('' != $dec_default) { | |
| 117 | - | |
| 118 | - $enc = $this->encryptString($dec_default, $u->user_id); | |
| 119 | - | |
| 120 | - if ($enc) { | |
| 121 | - | |
| 122 | - $ported = true; | |
| 123 | - $successes++; | |
| 124 | - update_user_meta($u->user_id, 'tfa_priv_key_64', $enc); | |
| 125 | - } | |
| 126 | - } | |
| 127 | - | |
| 128 | - } | |
| 129 | - | |
| 130 | - if ($ported) { | |
| 131 | - error_log("TFA: Successfully ported the key for user with ID ".$u->user_id." over to openssl"); | |
| 132 | - } else { | |
| 133 | - error_log("TFA: Failed to port the key for user with ID ".$u->user_id." over to openssl"); | |
| 134 | - } | |
| 135 | - } | |
| 136 | - if ($attempts == 0 || $successes > 0) update_site_option('simba_tfa_priv_key_format', 1); | |
| 137 | - | |
| 138 | - } | |
| 139 | - } | |
| 140 | - | |
| 141 | 91 | public function getPrivateKeyPlain($enc, $user_ID) |
| 142 | 92 | { |
| 143 | 93 | $dec = $this->decryptString($enc, $user_ID); |
| 144 | - $this->potentially_port_private_keys(); | |
| 145 | 94 | return $dec; |
| 146 | 95 | } |
| 147 | 96 | |
| 148 | 97 | |
| @@ -459,81 +408,37 @@ | ||
| 459 | 408 | return true; |
| 460 | 409 | |
| 461 | 410 | return false; |
| 462 | 411 | } |
| 463 | - | |
| 464 | - private function get_iv_size() { | |
| 465 | - // mcrypt first, for backwards compatibility | |
| 466 | - if (function_exists('mcrypt_get_iv_size')) { | |
| 467 | - return mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); | |
| 468 | - } elseif (function_exists('openssl_cipher_iv_length')) { | |
| 469 | - return openssl_cipher_iv_length('AES-128-CBC'); | |
| 470 | - } | |
| 471 | - throw new Exception('One of the mcrypt or openssl PHP modules needs to be installed'); | |
| 472 | - } | |
| 473 | - | |
| 474 | - private function create_iv($iv_size) { | |
| 475 | - if (function_exists('mcrypt_create_iv')) { | |
| 476 | - return mcrypt_create_iv($iv_size, MCRYPT_RAND); | |
| 477 | - } elseif (function_exists('openssl_random_pseudo_bytes')) { | |
| 478 | - return openssl_random_pseudo_bytes($iv_size); | |
| 479 | - } | |
| 480 | - throw new Exception('One of the mcrypt or openssl PHP modules needs to be installed'); | |
| 481 | - } | |
| 482 | - | |
| 483 | - private function encrypt($key, $string, $iv) { | |
| 484 | - // Prefer OpenSSL, because it uses correct padding, and its output can be decrypted by mcrypt - whereas, the converse is not true | |
| 485 | - if (function_exists('openssl_encrypt')) { | |
| 486 | - return openssl_encrypt($string, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv); | |
| 487 | - } elseif (function_exists('mcrypt_encrypt')) { | |
| 488 | - return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_CBC, $iv); | |
| 489 | - } | |
| 490 | - throw new Exception('One of the mcrypt or openssl PHP modules needs to be installed'); | |
| 491 | - } | |
| 492 | 412 | |
| 493 | - private function decrypt($key, $enc, $iv, $force_openssl = false) { | |
| 494 | - // Prefer mcrypt, because it can decrypt the output of both mcrypt_encrypt() and openssl_decrypt(), whereas (because of mcrypt_encrypt() using bad padding), the converse is not true | |
| 495 | - if (function_exists('mcrypt_decrypt') && !$force_openssl) { | |
| 496 | - return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $enc, MCRYPT_MODE_CBC, $iv); | |
| 497 | - } elseif (function_exists('openssl_decrypt')) { | |
| 498 | - $decrypted = openssl_decrypt($enc, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv); | |
| 499 | - if (false === $decrypted && !$force_openssl) { error_log("TFA decryption failure: was your site migrated to a server without mcrypt? You may need to install mcrypt, or disable TFA, in order to successfully decrypt data that was previously encrypted with mcrypt."); } | |
| 500 | - return $decrypted; | |
| 501 | - } | |
| 502 | - if ($force_openssl) return false; | |
| 503 | - throw new Exception('One of the mcrypt or openssl PHP modules needs to be installed'); | |
| 504 | - } | |
| 505 | - | |
| 506 | 413 | public function encryptString($string, $salt_suffix) |
| 507 | 414 | { |
| 508 | 415 | $key = $this->hashAndBin($this->pw_prefix.$salt_suffix, $this->salt_prefix.$salt_suffix); |
| 509 | 416 | |
| 510 | - $iv_size = $this->get_iv_size(); | |
| 511 | - $iv = $this->create_iv($iv_size); | |
| 417 | + $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); | |
| 418 | + $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); | |
| 512 | 419 | |
| 513 | - $enc = $this->encrypt($key, $string, $iv); | |
| 420 | + $enc = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_CBC, $iv); | |
| 514 | 421 | |
| 515 | - if (false === $enc) return false; | |
| 516 | - | |
| 517 | 422 | $enc = $iv.$enc; |
| 518 | 423 | $enc_b64 = base64_encode($enc); |
| 519 | 424 | return $enc_b64; |
| 520 | 425 | } |
| 521 | 426 | |
| 522 | - private function decryptString($enc_b64, $salt_suffix, $force_openssl = false) | |
| 427 | + private function decryptString($enc_b64, $salt_suffix) | |
| 523 | 428 | { |
| 524 | 429 | $key = $this->hashAndBin($this->pw_prefix.$salt_suffix, $this->salt_prefix.$salt_suffix); |
| 525 | 430 | |
| 526 | - $iv_size = $this->get_iv_size(); | |
| 431 | + $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); | |
| 527 | 432 | $enc_conc = base64_decode($enc_b64); |
| 528 | 433 | |
| 529 | 434 | $iv = substr($enc_conc, 0, $iv_size); |
| 530 | 435 | $enc = substr($enc_conc, $iv_size); |
| 531 | 436 | |
| 532 | - $string = $this->decrypt($key, $enc, $iv, $force_openssl); | |
| 437 | + $string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $enc, MCRYPT_MODE_CBC, $iv); | |
| 533 | 438 | |
| 534 | - // Remove padding bytes | |
| 535 | - return rtrim($string, "\x00..\x1F"); | |
| 439 | + // Remove zeroed bytes | |
| 440 | + return rtrim($string); | |
| 536 | 441 | } |
| 537 | 442 | |
| 538 | 443 | private function hashAndBin($pw, $salt) |
| 539 | 444 | { |