Subversion Repositories oidplus

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * OIDplus 2.0
  5.  * Copyright 2019 Daniel Marschall, ViaThinkSoft
  6.  *
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *     http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  */
  19.  
  20. class OIDplusSessionHandler {
  21.  
  22.         protected $secret = '';
  23.  
  24.         function __construct($secret) {
  25.                 // **PREVENTING SESSION HIJACKING**
  26.                 // Prevents javascript XSS attacks aimed to steal the session ID
  27.                 ini_set('session.cookie_httponly', 1);
  28.  
  29.                 // **PREVENTING SESSION FIXATION**
  30.                 // Session ID cannot be passed through URLs
  31.                 ini_set('session.use_only_cookies', 1);
  32.  
  33.                 // Uses a secure connection (HTTPS) if possible
  34.                 ini_set('session.cookie_secure', 1);
  35.  
  36.                 if (isset($_SERVER['REQUEST_URI'])) {
  37.                         $path = $_SERVER['REQUEST_URI'];
  38.                         ini_set('session.cookie_path', basename($path));
  39.                 }
  40.  
  41.                 ini_set('session.cookie_samesite', 'Lax');
  42.  
  43.                 session_name('OIDPLUS_SESHDLR');
  44.                 session_start();
  45.  
  46.                 $this->secret = $secret;
  47.         }
  48.  
  49.         function __destruct() {
  50.                 session_write_close();
  51.         }
  52.  
  53.         public function setValue($name, $value) {
  54.                 $_SESSION[$name] = self::encrypt($value, $this->secret);
  55.         }
  56.  
  57.         public function getValue($name) {
  58.                 if (!isset($_SESSION[$name])) return null;
  59.                 return self::decrypt($_SESSION[$name], $this->secret);
  60.         }
  61.  
  62.         protected static function encrypt($data, $key) {
  63.         $iv = random_bytes(16); // AES block size in CBC mode
  64.         // Encryption
  65.         $ciphertext = openssl_encrypt(
  66.             $data,
  67.             'AES-256-CBC',
  68.             mb_substr($key, 0, 32, '8bit'),
  69.             OPENSSL_RAW_DATA,
  70.             $iv
  71.         );
  72.         // Authentication
  73.         $hmac = hash_hmac(
  74.             'SHA256',
  75.             $iv . $ciphertext,
  76.             mb_substr($key, 32, null, '8bit'),
  77.             true
  78.         );
  79.         return $hmac . $iv . $ciphertext;
  80.     }
  81.  
  82.     protected static function decrypt($data, $key)
  83.     {
  84.         $hmac       = mb_substr($data, 0, 32, '8bit');
  85.         $iv         = mb_substr($data, 32, 16, '8bit');
  86.         $ciphertext = mb_substr($data, 48, null, '8bit');
  87.         // Authentication
  88.         $hmacNew = hash_hmac(
  89.             'SHA256',
  90.             $iv . $ciphertext,
  91.             mb_substr($key, 32, null, '8bit'),
  92.             true
  93.         );
  94.         if (! hash_equals($hmac, $hmacNew)) {
  95.             throw new Exception('Authentication failed');
  96.         }
  97.         // Decrypt
  98.         return openssl_decrypt(
  99.             $ciphertext,
  100.             'AES-256-CBC',
  101.             mb_substr($key, 0, 32, '8bit'),
  102.             OPENSSL_RAW_DATA,
  103.             $iv
  104.         );
  105.     }
  106. }
  107.