Skip to content

Commit

Permalink
Fix error where keys were not being rotated
Browse files Browse the repository at this point in the history
  • Loading branch information
csev committed May 15, 2024
1 parent 25d7c67 commit 8099990
Showing 1 changed file with 26 additions and 13 deletions.
39 changes: 26 additions & 13 deletions src/Core/Keyset.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@
* Helper class for Using Tsugi's internal global outgoing keyset
*/

// TODO: Make a configuration option and truncate the table in a MYSQL and PostgreSQL friendly way
// Also make an admin UI to manage this - but for now there will be reasonble data in this table to build code upon

// TODO: Add a private key encryption regime like Sakai

class Keyset {

public static $ttl = 10*60;
public static $expire = 5*60;
// public static $expire = 0; // Debug only
public static $verbose = false; // Debug only

// Auto populate and/or rotate the lti_keyset data
public static function maintain() {
Expand All @@ -27,9 +26,12 @@ public static function maintain() {
$now = time();
$apc_check = U::appCacheGet('keyset_last_check', 0);

$privkey = U::appCacheGet('keyset_privkey', null);
$kid = U::appCacheGet('keyset_kid', null);

$delta = abs($now-$apc_check);
if ( $apc_check > 0 && $delta < self::$expire ) {
// error_log("Keyset::maintain Last key rotation check seconds=".$delta);
if ( is_string($kid) && is_string($privkey) && $apc_check > 0 && $delta < self::$expire ) {
if ( self::$verbose ) error_log("Keyset::maintain Last key rotation check seconds=".$delta);
return;
}

Expand All @@ -43,7 +45,7 @@ public static function maintain() {
$now = new \DateTime($rows[0]['now']);
$create = new \DateTime($rows[0]['created_at']);
$delta = $now->diff($create, true);
$days = $delta->d;
$days = $delta->days;
}

if ( $days == -1 || $days >= 30) {
Expand All @@ -56,25 +58,34 @@ public static function maintain() {
VALUES (:title, :pubkey, :privkey)
";
$values = array(
":title" => 'From lti/database.php',
":title" => 'From Keyset:maintain()',
":pubkey" => $publicKey,
":privkey" => $privateKey,
);
$stmt = $PDOX->queryReturnError($sql, $values);

if ( $stmt->rowCount() > 0 ) {
error_log("KeySet::maintain table cleanup rows=".$stmt->rowCount());
}

$kid = LTIX::getKidForKey($publicKey);
error_log("Keyset::maintain Key rotated days=".$days." new kid=".$kid);

if ( ! $stmt->success ) {
error_log("Keyset::maintain Unable to insert new key into keyset\n");
return;
}

// Clean up very old records
$stmt = $PDOX->queryDie("DELETE FROM {$CFG->dbprefix}lti_keyset WHERE
created_at < (CURDATE() - INTERVAL 1 MONTH);");

} else {
error_log("Keyset::maintain No key rotation necessary days=".$days);
if ( self::$verbose ) error_log("Keyset::maintain No key rotation necessary days=".$days);
}
}

// Get the private key and kid
// Get the private key and kid - call by reference
public static function getSigning(&$privkey, &$kid) {
global $PDOX, $CFG;

Expand All @@ -89,7 +100,7 @@ public static function getSigning(&$privkey, &$kid) {
// No more than once per expiration period
$delta = abs($now-$last_load);
if ( is_string($kid) && is_string($privkey) && $delta < self::$expire ) {
// error_log("Keyset::getSigning cache hit seconds=".$delta);
if ( self::$verbose ) error_log("Keyset::getSigning cache hit seconds=".$delta);
return;
}

Expand All @@ -99,7 +110,7 @@ public static function getSigning(&$privkey, &$kid) {
$privkey = LTIX::decrypt_secret($row['privkey']);
$pubkey = $row['pubkey'];
$kid = LTIX::getKidForKey($pubkey);
error_log("Keyset::getSigning loaded key from database now=".$now." kid=".$kid);
if ( self::$verbose ) error_log("Keyset::getSigning loaded key from database now=".$now." kid=".$kid);

// Save for later
if ( is_string($kid) && is_string($privkey)) {
Expand All @@ -116,8 +127,10 @@ public static function getSigning(&$privkey, &$kid) {
public static function getCurrentKeys() {
global $PDOX, $CFG;

// TODO: Once we are convident this table exists switch to allRowsDie()
$stmt = $PDOX->queryReturnError(
// Make sure we have a key and it is recent
self::maintain();

$stmt = $PDOX->queryDie(
"SELECT pubkey FROM {$CFG->dbprefix}lti_keyset
WHERE deleted = 0 AND pubkey IS NOT NULL AND privkey IS NOT NULL
ORDER BY created_at DESC LIMIT 3"
Expand Down

0 comments on commit 8099990

Please sign in to comment.