Rev 827 | Rev 831 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 827 | Rev 830 | ||
---|---|---|---|
Line 1142... | Line 1142... | ||
1142 | $out = self::$system_id_cache; |
1142 | $out = self::$system_id_cache; |
1143 | } else { |
1143 | } else { |
1144 | $out = false; |
1144 | $out = false; |
1145 | 1145 | ||
1146 | if (self::getPkiStatus(true)) { |
1146 | if (self::getPkiStatus(true)) { |
1147 | $pubKey = OIDplus::config()->getValue('oidplus_public_key'); |
1147 | $pubKey = OIDplus::getSystemPublicKey(); |
1148 | $out = self::getSystemIdFromPubKey($pubKey); |
1148 | $out = self::getSystemIdFromPubKey($pubKey); |
1149 | } |
1149 | } |
1150 | self::$system_id_cache = $out; |
1150 | self::$system_id_cache = $out; |
1151 | } |
1151 | } |
1152 | if (!$out) return false; |
1152 | if (!$out) return false; |
Line 1168... | Line 1168... | ||
1168 | // Bug reports are more than 10 years old and nobody cares... |
1168 | // Bug reports are more than 10 years old and nobody cares... |
1169 | // Use our own config file |
1169 | // Use our own config file |
1170 | return __DIR__.'/../../vendor/phpseclib/phpseclib/phpseclib/openssl.cnf'; |
1170 | return __DIR__.'/../../vendor/phpseclib/phpseclib/phpseclib/openssl.cnf'; |
1171 | } |
1171 | } |
1172 | 1172 | ||
- | 1173 | private static function getPrivKeyPassphraseFilename() { |
|
- | 1174 | return OIDplus::localpath() . 'userdata/privkey_secret.php'; |
|
- | 1175 | } |
|
- | 1176 | ||
- | 1177 | private static function tryCreatePrivKeyPassphrase() { |
|
- | 1178 | $file = self::getPrivKeyPassphraseFilename(); |
|
- | 1179 | ||
- | 1180 | $passphrase = generateRandomString(64); |
|
- | 1181 | $cont = "<?php\n"; |
|
- | 1182 | $cont .= "// ATTENTION! This file was automatically generated by OIDplus to encrypt the private key\n"; |
|
- | 1183 | $cont .= "// that is located in your database configuration table. DO NOT ALTER OR DELETE THIS FILE,\n"; |
|
- | 1184 | $cont .= "// otherwise you will lose your OIDplus System-ID and all services connected with it!\n"; |
|
- | 1185 | $cont .= "\$passphrase = '$passphrase';\n"; |
|
- | 1186 | $cont .= "// End of file\n"; |
|
- | 1187 | ||
- | 1188 | @file_put_contents($file, $cont); |
|
- | 1189 | } |
|
- | 1190 | ||
- | 1191 | private static function getPrivKeyPassphrase() { |
|
- | 1192 | $file = self::getPrivKeyPassphraseFilename(); |
|
- | 1193 | if (!file_exists($file)) return false; |
|
- | 1194 | $cont = file_get_contents($file); |
|
- | 1195 | $m = array(); |
|
- | 1196 | if (!preg_match("@'(.+)'@isU", $cont, $m)) return false; |
|
- | 1197 | return $m[1]; |
|
- | 1198 | } |
|
- | 1199 | ||
- | 1200 | public static function getSystemPrivateKey() { |
|
- | 1201 | $privKey = OIDplus::config()->getValue('oidplus_private_key'); |
|
- | 1202 | if ($privKey == '') return false; |
|
- | 1203 | ||
- | 1204 | $passphrase = self::getPrivKeyPassphrase(); |
|
- | 1205 | if ($passphrase !== false) { |
|
- | 1206 | $privKey = decrypt_private_key($privKey, $passphrase); |
|
- | 1207 | } |
|
- | 1208 | ||
- | 1209 | if (is_privatekey_encrypted($privKey)) { |
|
- | 1210 | // This can happen if the key file has vanished |
|
- | 1211 | return false; |
|
- | 1212 | } |
|
- | 1213 | ||
- | 1214 | return $privKey; |
|
- | 1215 | } |
|
- | 1216 | ||
- | 1217 | public static function getSystemPublicKey() { |
|
- | 1218 | $pubKey = OIDplus::config()->getValue('oidplus_public_key'); |
|
- | 1219 | if ($pubKey == '') return false; |
|
- | 1220 | return $pubKey; |
|
- | 1221 | } |
|
- | 1222 | ||
1173 | public static function getPkiStatus($try_generate=false) { |
1223 | public static function getPkiStatus($try_generate=false) { |
1174 | if (!function_exists('openssl_pkey_new')) return false; |
1224 | if (!function_exists('openssl_pkey_new')) return false; |
1175 | 1225 | ||
- | 1226 | if ($try_generate) { |
|
1176 | // For debug purposes: Invalidate current key |
1227 | // For debug purposes: Invalidate current key once: |
1177 | //OIDplus::config()->setValue('oidplus_private_key', ''); |
1228 | //OIDplus::config()->setValue('oidplus_private_key', ''); |
1178 | 1229 | ||
1179 | $privKey = OIDplus::config()->getValue('oidplus_private_key'); |
1230 | $privKey = OIDplus::getSystemPrivateKey(); |
1180 | $pubKey = OIDplus::config()->getValue('oidplus_public_key'); |
1231 | $pubKey = OIDplus::getSystemPublicKey(); |
- | 1232 | if (!verify_private_public_key($privKey, $pubKey)) { |
|
- | 1233 | if ($pubKey) { |
|
- | 1234 | OIDplus::logger()->log("[WARN]A!", "The private/public key-pair is broken. A new key-pair will now be generated for your system. Your System-ID will change."); |
|
- | 1235 | } |
|
1181 | 1236 | ||
1182 | if ($try_generate && !verify_private_public_key($privKey, $pubKey)) { |
- | |
1183 | $pkey_config = array( |
1237 | $pkey_config = array( |
1184 | "digest_alg" => "sha512", |
1238 | "digest_alg" => "sha512", |
1185 | "private_key_bits" => defined('OPENSSL_SUPPLEMENT') ? 1024 : 2048, // openssl_supplement.inc.php is based on phpseclib, which is very slow. So we use 1024 bits instead of 2048 bits |
1239 | "private_key_bits" => defined('OPENSSL_SUPPLEMENT') ? 1024 : 2048, // openssl_supplement.inc.php is based on phpseclib, which is very slow. So we use 1024 bits instead of 2048 bits |
1186 | "private_key_type" => OPENSSL_KEYTYPE_RSA, |
1240 | "private_key_type" => OPENSSL_KEYTYPE_RSA, |
1187 | "config" => OIDplus::getOpenSslCnf() |
1241 | "config" => OIDplus::getOpenSslCnf() |
Line 1190... | Line 1244... | ||
1190 | // Create the private and public key |
1244 | // Create the private and public key |
1191 | $res = openssl_pkey_new($pkey_config); |
1245 | $res = openssl_pkey_new($pkey_config); |
1192 | if ($res === false) return false; |
1246 | if ($res === false) return false; |
1193 | 1247 | ||
1194 | // Extract the private key from $res to $privKey |
1248 | // Extract the private key from $res to $privKey |
1195 | // TODO: Should we password-protect it? e.g. with OIDplus-Server-Secret |
- | |
1196 | if (openssl_pkey_export($res, $privKey, null, $pkey_config) === false) return false; |
1249 | if (openssl_pkey_export($res, $privKey, null, $pkey_config) === false) return false; |
1197 | 1250 | ||
1198 | // Extract the public key from $res to $pubKey |
1251 | // Extract the public key from $res to $pubKey |
1199 | $tmp = openssl_pkey_get_details($res); |
1252 | $tmp = openssl_pkey_get_details($res); |
1200 | if ($tmp === false) return false; |
1253 | if ($tmp === false) return false; |
1201 | $pubKey = $tmp["key"]; |
1254 | $pubKey = $tmp["key"]; |
1202 | 1255 | ||
- | 1256 | // encrypt new keys using a passphrase stored in a secret file |
|
- | 1257 | self::tryCreatePrivKeyPassphrase(); // *try* (re)generate this file |
|
- | 1258 | $passphrase = self::getPrivKeyPassphrase(); |
|
1203 | // Log |
1259 | if ($passphrase !== false) { |
1204 | OIDplus::logger()->log("[INFO]A!", "Generating new SystemID using a new key pair"); |
1260 | $privKey = encrypt_private_key($privKey, $passphrase); |
- | 1261 | } |
|
1205 | 1262 | ||
- | 1263 | // Calculate the system ID from the public key |
|
- | 1264 | $system_id = self::getSystemIdFromPubKey($pubKey); |
|
- | 1265 | if ($system_id !== false) { |
|
1206 | // Save the key pair to database |
1266 | // Save the key pair to database |
1207 | OIDplus::config()->setValue('oidplus_private_key', $privKey); |
1267 | OIDplus::config()->setValue('oidplus_private_key', $privKey); |
1208 | OIDplus::config()->setValue('oidplus_public_key', $pubKey); |
1268 | OIDplus::config()->setValue('oidplus_public_key', $pubKey); |
1209 | 1269 | ||
1210 | // Log the new system ID |
1270 | // Log the new system ID |
- | 1271 | OIDplus::logger()->log("[INFO]A!", "A new private/public key-pair for your system had been generated. Your SystemID is now $system_id"); |
|
- | 1272 | } |
|
- | 1273 | } else { |
|
1211 | $system_id = self::getSystemIdFromPubKey($pubKey); |
1274 | $passphrase = self::getPrivKeyPassphrase(); |
- | 1275 | if (($passphrase === false) || !is_privatekey_encrypted($privKey)) { |
|
- | 1276 | // Upgrade to new encrypted keys |
|
- | 1277 | self::tryCreatePrivKeyPassphrase(); // *try* generate this file |
|
- | 1278 | $passphrase = self::getPrivKeyPassphrase(); |
|
1212 | if ($system_id !== false) { |
1279 | if ($passphrase !== false) { |
- | 1280 | $privKey = encrypt_private_key($privKey, $passphrase); |
|
- | 1281 | OIDplus::logger()->log("[INFO]A!", "The private/public key-pair has been upgraded to an encrypted key-pair. The key is saved in ".self::getPrivKeyPassphraseFilename()); |
|
1213 | OIDplus::logger()->log("[INFO]A!", "Your SystemID is now $system_id"); |
1282 | OIDplus::config()->setValue('oidplus_private_key', $privKey); |
- | 1283 | } |
|
- | 1284 | } |
|
1214 | } |
1285 | } |
1215 | } |
1286 | } |
1216 | 1287 | ||
- | 1288 | $privKey = OIDplus::getSystemPrivateKey(); |
|
- | 1289 | $pubKey = OIDplus::getSystemPublicKey(); |
|
1217 | return verify_private_public_key($privKey, $pubKey); |
1290 | return verify_private_public_key($privKey, $pubKey); |
1218 | } |
1291 | } |
1219 | 1292 | ||
1220 | public static function getInstallType() { |
1293 | public static function getInstallType() { |
1221 | $counter = 0; |
1294 | $counter = 0; |