diff --git a/www/admin/class_test.db.single.php b/www/admin/class_test.db.single.php
index c70edb4c..778e2730 100644
--- a/www/admin/class_test.db.single.php
+++ b/www/admin/class_test.db.single.php
@@ -21,10 +21,7 @@ $ECHO_ALL = true;
$LOG_FILE_ID = 'classTest-db-single';
ob_end_flush();
-use CoreLibs\Debug\Support as DgS;
-use CoreLibs\DB\IO as DbIo;
use CoreLibs\Debug\Support;
-use CoreLibs\Convert\SetVarType;
$log = new CoreLibs\Debug\Logging([
'log_folder' => BASE . LOG,
diff --git a/www/admin/class_test.encryption.php b/www/admin/class_test.encryption.php
new file mode 100644
index 00000000..75185cf4
--- /dev/null
+++ b/www/admin/class_test.encryption.php
@@ -0,0 +1,111 @@
+ BASE . LOG,
+ 'file_id' => $LOG_FILE_ID,
+ // add file date
+ 'print_file_date' => true,
+ // set debug and print flags
+ 'debug_all' => $DEBUG_ALL,
+ 'echo_all' => $ECHO_ALL ?? false,
+ 'print_all' => $PRINT_ALL,
+]);
+
+
+// define a list of from to color sets for conversion test
+
+$PAGE_NAME = 'TEST CLASS: ENCRYPTION';
+print "";
+print "
" . $PAGE_NAME . "";
+print "";
+print '';
+print '' . $PAGE_NAME . '
';
+
+$key = CreateKey::generateRandomKey();
+print "Secret Key: " . $key . "
";
+
+$string = "I a some deep secret";
+$encrypted = SymmetricEncryption::encrypt($string, $key);
+$decrypted = SymmetricEncryption::decrypt($encrypted, $key);
+
+print "Original: " . $string . "
";
+print "Encrypted: " . $encrypted . "
";
+print "Decrytped: " . $decrypted . "
";
+
+print "
WRONG CIPHERTEXT
";
+try {
+ $decrypted = SymmetricEncryption::decrypt('flupper', $key);
+} catch (Exception $e) {
+ print "Error: " . $e->getMessage() . "
";
+}
+
+print "
SHORT and WRONG KEY
";
+$key = 'wrong_key';
+try {
+ $encrypted = SymmetricEncryption::encrypt($string, $key);
+} catch (Exception $e) {
+ print "Error: " . $e->getMessage() . "
";
+}
+
+print "
INVALID HEX KEY
";
+$key = '1cabd5cba9e042f12522f4ff2de5c31d233b';
+try {
+ $encrypted = SymmetricEncryption::encrypt($string, $key);
+} catch (Exception $e) {
+ print "Error: " . $e->getMessage() . "
";
+}
+
+print "
WRONG KEY TO DECRYPT
";
+$key = CreateKey::generateRandomKey();
+$string = "I a some deep secret";
+$encrypted = SymmetricEncryption::encrypt($string, $key);
+$key = CreateKey::generateRandomKey();
+try {
+ $decrypted = SymmetricEncryption::decrypt($encrypted, $key);
+} catch (Exception $e) {
+ print "Error: " . $e->getMessage() . "
";
+}
+
+print "
WRONG KEY TO DECRYPT
";
+$key = CreateKey::generateRandomKey();
+$string = "I a some deep secret";
+$encrypted = SymmetricEncryption::encrypt($string, $key);
+$key = 'wrong_key';
+try {
+ $decrypted = SymmetricEncryption::decrypt($encrypted, $key);
+} catch (Exception $e) {
+ print "Error: " . $e->getMessage() . "
";
+}
+
+// error message
+print $log->printErrorMsg();
+
+print "";
+
+// __END__
diff --git a/www/admin/class_test.password.php b/www/admin/class_test.password.php
index 73312bb2..3ca8e668 100644
--- a/www/admin/class_test.password.php
+++ b/www/admin/class_test.password.php
@@ -20,10 +20,10 @@ define('USE_DATABASE', false);
// sample config
require 'config.php';
// define log file id
-$LOG_FILE_ID = 'classTest-pass';
+$LOG_FILE_ID = 'classTest-password';
ob_end_flush();
-use CoreLibs\Check\Password as PwdChk;
+use CoreLibs\Security\Password as PwdChk;
$log = new CoreLibs\Debug\Logging([
'log_folder' => BASE . LOG,
@@ -35,8 +35,8 @@ $log = new CoreLibs\Debug\Logging([
'echo_all' => $ECHO_ALL ?? false,
'print_all' => $PRINT_ALL,
]);
-$_password = new CoreLibs\Check\Password();
-$password_class = 'CoreLibs\Check\Password';
+$_password = new CoreLibs\Security\Password();
+$password_class = 'CoreLibs\Security\Password';
// define a list of from to color sets for conversion test
diff --git a/www/composer.lock b/www/composer.lock
index b5f4f8b1..0c2e8a47 100644
--- a/www/composer.lock
+++ b/www/composer.lock
@@ -12,7 +12,7 @@
"dist": {
"type": "path",
"url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All",
- "reference": "c7ec1300b779f5ebc9dce52d4ce5484e4d22e9c2"
+ "reference": "b16ff4c613f6f76e8f518d47b4a04c1b914fee82"
},
"require": {
"php": ">=8.1"
diff --git a/www/vendor/composer/installed.json b/www/vendor/composer/installed.json
index fba64cd4..dd91d0b8 100644
--- a/www/vendor/composer/installed.json
+++ b/www/vendor/composer/installed.json
@@ -7,7 +7,7 @@
"dist": {
"type": "path",
"url": "/storage/var/www/html/developers/clemens/core_data/composer-packages/CoreLibs-Composer-All",
- "reference": "c7ec1300b779f5ebc9dce52d4ce5484e4d22e9c2"
+ "reference": "b16ff4c613f6f76e8f518d47b4a04c1b914fee82"
},
"require": {
"php": ">=8.1"
diff --git a/www/vendor/composer/installed.php b/www/vendor/composer/installed.php
index 9d2847ab..4f5409bd 100644
--- a/www/vendor/composer/installed.php
+++ b/www/vendor/composer/installed.php
@@ -13,7 +13,7 @@
'egrajp/corelibs-composer-all' => array(
'pretty_version' => 'dev-development',
'version' => 'dev-development',
- 'reference' => 'c7ec1300b779f5ebc9dce52d4ce5484e4d22e9c2',
+ 'reference' => 'b16ff4c613f6f76e8f518d47b4a04c1b914fee82',
'type' => 'library',
'install_path' => __DIR__ . '/../egrajp/corelibs-composer-all',
'aliases' => array(),
diff --git a/www/vendor/egrajp/corelibs-composer-all/publish/last.published b/www/vendor/egrajp/corelibs-composer-all/publish/last.published
index 56b6be4e..a2f28f43 100644
--- a/www/vendor/egrajp/corelibs-composer-all/publish/last.published
+++ b/www/vendor/egrajp/corelibs-composer-all/publish/last.published
@@ -1 +1 @@
-8.3.1
+8.4.0
diff --git a/www/vendor/egrajp/corelibs-composer-all/src/ACL/Login.php b/www/vendor/egrajp/corelibs-composer-all/src/ACL/Login.php
index c4126be7..e657ee19 100644
--- a/www/vendor/egrajp/corelibs-composer-all/src/ACL/Login.php
+++ b/www/vendor/egrajp/corelibs-composer-all/src/ACL/Login.php
@@ -68,7 +68,7 @@ declare(strict_types=1);
namespace CoreLibs\ACL;
-use CoreLibs\Check\Password;
+use CoreLibs\Security\Password;
use CoreLibs\Convert\Json;
class Login
@@ -1608,7 +1608,7 @@ class Login
// TODO: submit or JS to set target page as ajax call
// NOTE: for the HTML block I ignore line lengths
// phpcs:disable
- $this->login_template['password_change'] = <<login_template['password_change'] = <<
{TITLE_PASSWORD_CHANGE} |
@@ -1626,7 +1626,7 @@ class Login
{PASSWORD_CHANGE_SHOW}
-EOM;
+HTML;
// phpcs:enable
}
if ($this->password_forgot) {
@@ -1650,7 +1650,7 @@ EOM;
// now check templates
// TODO: submit or JS to set target page as ajax call
if (!$this->login_template['template']) {
- $this->login_template['template'] = <<login_template['template'] = <<
@@ -1712,7 +1712,7 @@ h3 { font-size: 18px; }
-EOM;
+HTML;
}
}
diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Basic.php b/www/vendor/egrajp/corelibs-composer-all/src/Basic.php
index a9a70c52..7e1882e8 100644
--- a/www/vendor/egrajp/corelibs-composer-all/src/Basic.php
+++ b/www/vendor/egrajp/corelibs-composer-all/src/Basic.php
@@ -1164,7 +1164,7 @@ class Basic
public function passwordSet(string $password): string
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Check\Password::passwordSet()', E_USER_DEPRECATED);
- return \CoreLibs\Check\Password::passwordSet($password);
+ return \CoreLibs\Security\Password::passwordSet($password);
}
/**
@@ -1177,7 +1177,7 @@ class Basic
public function passwordVerify(string $password, string $hash): bool
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Check\Password::passwordVerify()', E_USER_DEPRECATED);
- return \CoreLibs\Check\Password::passwordVerify($password, $hash);
+ return \CoreLibs\Security\Password::passwordVerify($password, $hash);
}
/**
@@ -1189,7 +1189,7 @@ class Basic
public function passwordRehashCheck(string $hash): bool
{
trigger_error('Method ' . __METHOD__ . ' is deprecated, use \CoreLibs\Check\Password::passwordRehashCheck()', E_USER_DEPRECATED);
- return \CoreLibs\Check\Password::passwordRehashCheck($hash);
+ return \CoreLibs\Security\Password::passwordRehashCheck($hash);
}
// *** BETTER PASSWORD OPTIONS END ***
diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Check/Password.php b/www/vendor/egrajp/corelibs-composer-all/src/Check/Password.php
index 1475064c..f1f588b1 100644
--- a/www/vendor/egrajp/corelibs-composer-all/src/Check/Password.php
+++ b/www/vendor/egrajp/corelibs-composer-all/src/Check/Password.php
@@ -1,6 +1,8 @@
db_functions->__dbPrintLastError();
if ($cursor !== false) {
- $pg_error_string = $this->db_functions->__dbPrintError($cursor);
+ [$db_prefix, $db_error_string] = $this->db_functions->__dbPrintError($cursor);
}
if ($cursor === false && method_exists($this->db_functions, '__dbPrintError')) {
- $pg_error_string = $this->db_functions->__dbPrintError();
+ [$db_prefix, $db_error_string] = $this->db_functions->__dbPrintError();
}
- if ($pg_error_string) {
- $this->__dbDebug('db', $pg_error_string, 'DB_ERROR', $where_called);
+ // prefix the master if not the same
+ if (
+ !empty($db_error_string_last) &&
+ trim($db_error_string) != trim($db_error_string_last)
+ ) {
+ $db_error_string =
+ $db_prefix_last . ' ' . $db_error_string_last . ';'
+ . $db_prefix . ' ' . $db_error_string;
+ } elseif (!empty($db_error_string)) {
+ $db_error_string = $db_prefix . ' ' . $db_error_string;
}
- return [$where_called, $pg_error_string];
+ if ($db_error_string) {
+ $this->__dbDebug('db', $db_error_string, 'DB_ERROR', $where_called);
+ }
+ return [
+ $where_called,
+ $db_error_string
+ ];
}
/**
@@ -902,11 +920,14 @@ class IO
// because the placeholders start with $ and at 1,
// we need to increase each key and prefix it with a $ char
for ($i = 0, $iMax = count($keys); $i < $iMax; $i++) {
- $keys[$i] = '$' . ($keys[$i] + 1);
+ // note: if I use $ here, the str_replace will
+ // replace it again. eg $11 '$1'1would be replaced with $1 again
// prefix data set with parameter pos
- $data[$i] = $keys[$i] . ':' . ($data[$i] === null ?
+ $data[$i] = '#' . ($keys[$i] + 1) . ':' . ($data[$i] === null ?
'"NULL"' : (string)$data[$i]
);
+ // search part
+ $keys[$i] = '$' . ($keys[$i] + 1);
}
// simply replace the $1, $2, ... with the actual data and return it
return str_replace(
diff --git a/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/Interface/SqlFunctions.php b/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/Interface/SqlFunctions.php
index 5aa7fdb5..7e81a164 100644
--- a/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/Interface/SqlFunctions.php
+++ b/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/Interface/SqlFunctions.php
@@ -209,10 +209,17 @@ interface SqlFunctions
/**
* Undocumented function
*
- * @param \PgSql\Result|false $cursor
- * @return string
+ * @return array{0:string,1:string}
*/
- public function __dbPrintError(\PgSql\Result|false $cursor = false): string;
+ public function __dbPrintLastError(): array;
+
+ /**
+ * Undocumented function
+ *
+ * @param \PgSql\Result|false $cursor
+ * @return array{0:string,1:string}
+ */
+ public function __dbPrintError(\PgSql\Result|false $cursor = false): array;
/**
* Undocumented function
diff --git a/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/PgSQL.php b/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/PgSQL.php
index 9f42f76a..2d9b34eb 100644
--- a/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/PgSQL.php
+++ b/www/vendor/egrajp/corelibs-composer-all/src/DB/SQL/PgSQL.php
@@ -61,7 +61,7 @@ class PgSQL implements Interface\SqlFunctions
/** @var string */
private $last_error_query;
/** @var \PgSql\Connection|false */
- private $dbh;
+ private $dbh = false;
/**
* queries last error query and returns true or false if error was set
@@ -532,18 +532,37 @@ class PgSQL implements Interface\SqlFunctions
return $this->dbh;
}
+ /**
+ * Returns last error for active cursor
+ *
+ * @return array{0:string,1:string} prefix, error string
+ */
+ public function __dbPrintLastError(): array
+ {
+ if (is_bool($this->dbh)) {
+ return ['', ''];
+ }
+ if (!empty($error_message = pg_last_error($this->dbh))) {
+ return [
+ '-PostgreSQL-Error-Last-',
+ $error_message
+ ];
+ }
+ return ['', ''];
+ }
+
/**
* reads the last error for this cursor and returns
* html formatted string with error name
*
* @param \PgSql\Result|false $cursor cursor
- * or null
- * @return string error string
+ * or null
+ * @return array{0:string,1:string} prefix, error string
*/
- public function __dbPrintError(\PgSql\Result|false $cursor = false): string
+ public function __dbPrintError(\PgSql\Result|false $cursor = false): array
{
if (is_bool($this->dbh)) {
- return '';
+ return ['', ''];
}
// run the query again for the error result here
if ((is_bool($cursor)) && $this->last_error_query) {
@@ -552,10 +571,12 @@ class PgSQL implements Interface\SqlFunctions
$cursor = pg_get_result($this->dbh);
}
if ($cursor && $error_str = pg_result_error($cursor)) {
- return '-PostgreSQL-Error- '
- . $error_str;
+ return [
+ '-PostgreSQL-Error-',
+ $error_str
+ ];
} else {
- return '';
+ return ['', ''];
}
}
diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/Generate.php b/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/Generate.php
index 65555bc3..90daccc8 100644
--- a/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/Generate.php
+++ b/www/vendor/egrajp/corelibs-composer-all/src/Output/Form/Generate.php
@@ -1954,7 +1954,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
if ($this->table_array[$key]['value']) {
// use the better new passwordSet instead of crypt based
$this->table_array[$key]['value'] =
- \CoreLibs\Check\Password::passwordSet($this->table_array[$key]['value']);
+ \CoreLibs\Security\Password::passwordSet($this->table_array[$key]['value']);
$this->table_array[$key]['HIDDEN_value'] = $this->table_array[$key]['value'];
} else {
// $this->table_array[$key]['HIDDEN_value'] =
diff --git a/www/vendor/egrajp/corelibs-composer-all/src/Security/CreateKey.php b/www/vendor/egrajp/corelibs-composer-all/src/Security/CreateKey.php
new file mode 100644
index 00000000..add2773e
--- /dev/null
+++ b/www/vendor/egrajp/corelibs-composer-all/src/Security/CreateKey.php
@@ -0,0 +1,61 @@
+dbExec("DROP TABLE test_meta");
}
// uid is for internal reference tests
- $base_table = <<dbExec(
// primary key name is table + '_id'
- <<dbExec(
- <<dbExec(
- << false,
'array dims' => 0,
'is enum' => false,
- 'is base' => 1,
+ 'is base' => true,
'is composite' => false,
- 'is pesudo' => false,
'description' => '',
+ 'is pseudo' => false
],
'row_2' => [
'num' => 2,
@@ -1355,10 +1355,10 @@ final class CoreLibsDBIOTest extends TestCase
'has default' => false,
'array dims' => 0,
'is enum' => false,
- 'is base' => 1,
+ 'is base' => true,
'is composite' => false,
- 'is pesudo' => false,
'description' => '',
+ 'is pseudo' => false
]
]
],
@@ -1374,10 +1374,10 @@ final class CoreLibsDBIOTest extends TestCase
'has default' => false,
'array dims' => 0,
'is enum' => false,
- 'is base' => 1,
+ 'is base' => true,
'is composite' => false,
- 'is pesudo' => false,
'description' => '',
+ 'is pseudo' => false
],
'row_2' => [
'num' => 2,
@@ -1387,10 +1387,10 @@ final class CoreLibsDBIOTest extends TestCase
'has default' => false,
'array dims' => 0,
'is enum' => false,
- 'is base' => 1,
+ 'is base' => true,
'is composite' => false,
- 'is pesudo' => false,
'description' => '',
+ 'is pseudo' => false
]
]
],
@@ -4425,16 +4425,16 @@ final class CoreLibsDBIOTest extends TestCase
]
]
],
- // same but as EOM
- 'single insert (PK), EOM string' => [
- << [
+ << [
- << [
+ <<assertEquals(
$expected,
- \CoreLibs\Check\Password::passwordVerify($input, \CoreLibs\Check\Password::passwordSet($input_hash))
+ \CoreLibs\Security\Password::passwordVerify($input, \CoreLibs\Security\Password::passwordSet($input_hash))
);
}
@@ -65,7 +65,7 @@ final class CoreLibsCheckPasswordTest extends TestCase
{
$this->assertEquals(
$expected,
- \CoreLibs\Check\Password::passwordRehashCheck($input)
+ \CoreLibs\Security\Password::passwordRehashCheck($input)
);
}
}
diff --git a/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Security/CoreLibsSecuritySymmetricEncryption.php b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Security/CoreLibsSecuritySymmetricEncryption.php
new file mode 100644
index 00000000..9e2773da
--- /dev/null
+++ b/www/vendor/egrajp/corelibs-composer-all/test/phpunit/Security/CoreLibsSecuritySymmetricEncryption.php
@@ -0,0 +1,172 @@
+ [
+ 'input' => 'I am a secret',
+ 'expected' => 'I am a secret',
+ ],
+ ];
+ }
+
+ /**
+ * test encrypt/decrypt produce correct output
+ *
+ * @covers ::generateRandomKey
+ * @covers ::encrypt
+ * @covers ::decrypt
+ * @dataProvider providerEncryptDecryptSuccess
+ * @testdox encrypt/decrypt $input must be $expected [$_dataName]
+ *
+ * @param string $input
+ * @param string $expected
+ * @return void
+ */
+ public function testEncryptDecryptSuccess(string $input, string $expected): void
+ {
+ $key = CreateKey::generateRandomKey();
+ $encrypted = SymmetricEncryption::encrypt($input, $key);
+ $decrypted = SymmetricEncryption::decrypt($encrypted, $key);
+
+ $this->assertEquals(
+ $expected,
+ $decrypted
+ );
+ }
+
+ /**
+ * Undocumented function
+ *
+ * @return array
+ */
+ public function providerEncryptFailed(): array
+ {
+ return [
+ 'wrong decryption key' => [
+ 'input' => 'I am a secret',
+ 'excpetion_message' => 'Invalid Key'
+ ],
+ ];
+ }
+
+ /**
+ * Test decryption with wrong key
+ *
+ * @covers ::generateRandomKey
+ * @covers ::encrypt
+ * @covers ::decrypt
+ * @dataProvider providerEncryptFailed
+ * @testdox decrypt with wrong key $input throws $exception_message [$_dataName]
+ *
+ * @param string $input
+ * @param string $exception_message
+ * @return void
+ */
+ public function testEncryptFailed(string $input, string $exception_message): void
+ {
+ $key = CreateKey::generateRandomKey();
+ $encrypted = SymmetricEncryption::encrypt($input, $key);
+ $wrong_key = CreateKey::generateRandomKey();
+ $this->expectExceptionMessage($exception_message);
+ SymmetricEncryption::decrypt($encrypted, $wrong_key);
+ }
+
+ /**
+ * Undocumented function
+ *
+ * @return array
+ */
+ public function providerWrongKey(): array
+ {
+ return [
+ 'not hex key' => [
+ 'key' => 'not_a_hex_key',
+ 'exception_message' => 'Invalid hex key'
+ ],
+ 'too short hex key' => [
+ 'key' => '1cabd5cba9e042f12522f4ff2de5c31d233b',
+ 'excpetion_message' => 'Key is not the correct size (must be '
+ . 'SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long).'
+ ],
+ ];
+ }
+
+ /**
+ * test invalid key provided to decrypt or encrypt
+ *
+ * @covers ::encrypt
+ * @covers ::decrypt
+ * @dataProvider providerWrongKey
+ * @testdox wrong key $key throws $exception_message [$_dataName]
+ *
+ * @param string $key
+ * @param string $exception_message
+ * @return void
+ */
+ public function testWrongKey(string $key, string $exception_message): void
+ {
+ $this->expectExceptionMessage($exception_message);
+ SymmetricEncryption::encrypt('test', $key);
+ // we must encrypt valid thing first so we can fail with the wrong kjey
+ $enc_key = CreateKey::generateRandomKey();
+ $encrypted = SymmetricEncryption::encrypt('test', $enc_key);
+ $this->expectExceptionMessage($exception_message);
+ SymmetricEncryption::decrypt($encrypted, $key);
+ }
+
+ /**
+ * Undocumented function
+ *
+ * @return array
+ */
+ public function providerWrongCiphertext(): array
+ {
+ return [
+ 'too short ciphertext' => [
+ 'input' => 'short',
+ 'exception_message' => 'Invalid ciphertext (too short)'
+ ],
+ ];
+ }
+
+ /**
+ * Undocumented function
+ *
+ * @covers ::decrypt
+ * @dataProvider providerWrongCiphertext
+ * @testdox too short ciphertext $input throws $exception_message [$_dataName]
+ *
+ * @param string $input
+ * @param string $exception_message
+ * @return void
+ */
+ public function testWrongCiphertext(string $input, string $exception_message): void
+ {
+ $key = CreateKey::generateRandomKey();
+ $this->expectExceptionMessage($exception_message);
+ SymmetricEncryption::decrypt($input, $key);
+ }
+}
+
+// __END__