diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 37a2c369..86eaa108 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -2,6 +2,10 @@ - Introduced the raw: search label - Added Italian translation. Credits: Stefano Gatto - timestamp signing sorts by 'id' column +- timestamp hash value defaults to sha256 + +Be sure to apply util/db-upgrade.sql + 1.3.12: ------- diff --git a/util/db-mysql.sql b/util/db-mysql.sql index f90bc19e..0563ceeb 100644 --- a/util/db-mysql.sql +++ b/util/db-mysql.sql @@ -463,7 +463,7 @@ create table if not exists `timestamp` ( `id` bigint unsigned not null auto_increment, `start_id` bigint default 0, `stop_id` bigint default 0, - `hash_value` char(40), + `hash_value` varchar(128), `count` int default 0, `response_time` bigint default 0, `response_string` blob not null, diff --git a/util/db-upgrade.sql b/util/db-upgrade.sql new file mode 100644 index 00000000..c5a97332 --- /dev/null +++ b/util/db-upgrade.sql @@ -0,0 +1 @@ +alter table timestamp change column hash_value hash_value varchar(128) default null; diff --git a/util/sign.php b/util/sign.php index 26d3f575..b3c4110d 100644 --- a/util/sign.php +++ b/util/sign.php @@ -12,11 +12,13 @@ ini_set("session.save_path", "/tmp"); $webuidir = ""; $verbose = 0; $mode = "unit"; +$algo = "sha256"; $opts = 'h::v'; $lopts = array( 'webui:', 'mode:', + 'algo:', 'verbose' ); @@ -37,6 +39,10 @@ if ( $options = getopt( $opts, $lopts ) ) $mode = $options['mode']; } + if ( isset($options['algo']) ) { + $algo = $options['algo']; + } + if ( isset($options['h']) ) { display_help(); @@ -66,6 +72,7 @@ Registry::set('db', $db); Registry::set('DB_DRIVER', DB_DRIVER); define('MODE', $mode); +define('ALGO', $algo); $data = get_hash_values(); @@ -143,7 +150,7 @@ function get_hash_values() { START_ID => $start_id, STOP_ID => $stop_id, COUNT => $count, - HASH_VALUE => sha1($s) + HASH_VALUE => hash(ALGO, $s) ]; } diff --git a/webui/model/search/message.php b/webui/model/search/message.php index 4fb5bea7..8399fbed 100644 --- a/webui/model/search/message.php +++ b/webui/model/search/message.php @@ -371,7 +371,14 @@ class ModelSearchMessage extends Model { $s .= $q['digest']; } - $computed_hash = sha1($s); + $len = strlen($query->row['hash_value']); + if($len == 64) + $algo='sha256'; + elseif($len == 128) + $algo='sha512'; + else + $algo='sha1'; + $computed_hash = hash($algo, $s); if(MEMCACHED_ENABLED) { $memcache->add($cache_key, $computed_hash, 0, MEMCACHED_TTL); diff --git a/webui/system/helper/TrustedTimestamps.php b/webui/system/helper/TrustedTimestamps.php index 9dc702e5..182c7a42 100644 --- a/webui/system/helper/TrustedTimestamps.php +++ b/webui/system/helper/TrustedTimestamps.php @@ -15,6 +15,11 @@ * http://www.slproweb.com/products/Win32OpenSSL.html * http://www.switch.ch/aai/support/howto/openssl-windows.html * + * 2021-10-26 Frank Schmirler: + * - extract certificate chain from TSResponse and feed into ts -verify as -untrusted + * - unlink temporary files + * - support for sha256 and sha512 hashes + * * @version 0.3 * @author David Müller * @package trustedtimestamps @@ -25,16 +30,22 @@ class TrustedTimestamps /** * Creates a Timestamp Requestfile from a hash * - * @param string $hash: The hashed data (sha1) + * @param string $hash: The hashed data (sha1, sha256 or sha512) * @return string: path of the created timestamp-requestfile */ public static function createRequestfile ($hash) { - if (strlen($hash) !== 40) + if (strlen($hash) === 40) + $digest="-sha1"; + elseif (strlen($hash) === 64) + $digest="-sha256"; + elseif (strlen($hash) === 128) + $digest="-sha512"; + else throw new Exception("Invalid Hash."); $outfilepath = self::createTempFile(); - $cmd = OPENSSL_BINARY . " ts -query -digest ".escapeshellarg($hash)." -cert -out ".escapeshellarg($outfilepath); + $cmd = OPENSSL_BINARY . " ts -query $digest -digest ".escapeshellarg($hash)." -cert -out ".escapeshellarg($outfilepath); $retarray = array(); exec($cmd." 2>&1", $retarray, $retcode); @@ -106,6 +117,8 @@ class TrustedTimestamps $retarray = array(); exec($cmd." 2>&1", $retarray, $retcode); + unlink($responsefile); + if ($retcode !== 0) throw new Exception("The reply failed: ".implode(", ", $retarray)); @@ -144,7 +157,7 @@ class TrustedTimestamps */ public static function validate ($hash, $base64_response_string, $response_time, $tsa_cert_file) { - if (strlen($hash) !== 40) + if (strlen($hash) !== 40 && strlen($hash) !== 64 && strlen($hash) !== 128) throw new Exception("Invalid Hash"); $binary_response_string = base64_decode($base64_response_string); @@ -160,11 +173,22 @@ class TrustedTimestamps $responsefile = self::createTempFile($binary_response_string); - $cmd = OPENSSL_BINARY . " ts -verify -digest ".escapeshellarg($hash)." -in ".escapeshellarg($responsefile)." -CAfile ".escapeshellarg($tsa_cert_file); + /* + * extract chain from response + * openssl ts -verify does not include them for verification despite of the man page stating otherwise + */ + $untrustedfile = self::createTempFile(); + $cmd = OPENSSL_BINARY . " ts -reply -in ".escapeshellarg($responsefile)." -token_out | " . OPENSSL_BINARY . " pkcs7 -inform DER -print_certs -out ".escapeshellarg($untrustedfile); + shell_exec($cmd); + + $cmd = OPENSSL_BINARY . " ts -verify -digest ".escapeshellarg($hash)." -in ".escapeshellarg($responsefile)." -CAfile ".escapeshellarg($tsa_cert_file)." -untrusted ".escapeshellarg($untrustedfile); $retarray = array(); exec($cmd." 2>&1", $retarray, $retcode); + unlink($untrustedfile); + unlink($responsefile); + /* * just 2 "normal" cases: * 1) Everything okay -> retcode 0 + retarray[0] == "Verification: OK"