1<?php declare(strict_types = 1); 2/* 3** Zabbix 4** Copyright (C) 2001-2021 Zabbix SIA 5** 6** This program is free software; you can redistribute it and/or modify 7** it under the terms of the GNU General Public License as published by 8** the Free Software Foundation; either version 2 of the License, or 9** (at your option) any later version. 10** 11** This program is distributed in the hope that it will be useful, 12** but WITHOUT ANY WARRANTY; without even the implied warranty of 13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14** GNU General Public License for more details. 15** 16** You should have received a copy of the GNU General Public License 17** along with this program; if not, write to the Free Software 18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19**/ 20 21 22/** 23 * Helper class for sign / encrypt data. 24 */ 25class CEncryptHelper { 26 27 /** 28 * Signature algorithm. 29 */ 30 public const SIGN_ALGO = 'sha256'; 31 32 /** 33 * Session secret key. 34 * 35 * @var string 36 */ 37 private static $key; 38 39 /** 40 * Return session key. 41 * 42 * @return string|null 43 */ 44 private static function getKey(): ?string { 45 if (!self::$key) { 46 // This if contain copy in CEncryptedCookieSession class. 47 if (CSettingsHelper::getGlobal(CSettingsHelper::SESSION_KEY) === '') { 48 self::$key = self::generateKey(); 49 50 if (!self::updateKey(self::$key)) { 51 return null; 52 } 53 54 return self::$key; 55 } 56 57 self::$key = CSettingsHelper::getGlobal(CSettingsHelper::SESSION_KEY); 58 } 59 60 return self::$key; 61 } 62 63 /** 64 * Timing attack safe string comparison. 65 * 66 * @param string $known_string 67 * @param string $user_string 68 * 69 * @return boolean 70 */ 71 public static function checkSign(string $known_string, string $user_string): bool { 72 return hash_equals($known_string, $user_string); 73 } 74 75 /** 76 * Encrypt string with session key. 77 * 78 * @param string $data 79 * 80 * @return string 81 */ 82 public static function sign(string $data): string { 83 $key = self::getKey(); 84 85 return hash_hmac(self::SIGN_ALGO, $data, $key, false); 86 } 87 88 /** 89 * Generate random 16 bytes key. 90 * 91 * @return string 92 */ 93 public static function generateKey(): string { 94 return bin2hex(openssl_random_pseudo_bytes(16)); 95 } 96 97 /** 98 * Update secret session key. 99 * 100 * @param string $key 101 * 102 * @return boolean 103 */ 104 public static function updateKey(string $key): bool { 105 $db_config = DB::select('config', ['output' => ['configid']])[0]; 106 107 return DBexecute( 108 'UPDATE config'. 109 ' SET session_key='.zbx_dbstr($key). 110 ' WHERE '.dbConditionInt('configid', [$db_config['configid']]) 111 ); 112 } 113} 114