You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
4.6 KiB
PHP

<?php
/**
* Created by PhpStorm.
* User: eater
* Date: 4/4/16
* Time: 9:25 PM
*/
namespace Eater\Glim\Service;
use Eater\Glim\Core;
class CA extends Main
{
public function getPrivateKey()
{
/** @var Core $core */
$core = $this->get('core');
return file_get_contents($core->getBaseDir() . '/storage/ca/ca.key');
}
/**
* @return string
*/
public function getOpenSslError()
{
$error = "";
while ($msg = openssl_error_string()) {
$error .= $msg . "\n";
}
return $error;
}
/**
* Signs a client certificate and returns the signed certificate
* @param string $csr
* @return string
* @throws \Exception
*/
public function signClientCsr($csr)
{
/** @var Core $core */
$core = $this->get('core');
$csrPath = tempnam(sys_get_temp_dir(), '0.');
$crtPath = tempnam(sys_get_temp_dir(), '0.');
file_put_contents($csrPath, $csr);
exec(escapeshellcmd($core->getBaseDir() . '/bin/sign-client-csr') . ' ' . escapeshellarg($csrPath) . ' ' . escapeshellarg($crtPath) . ' 2>&1', $output, $exitCode);
if ($exitCode !== 0) {
throw new \Exception("Failed signing CSR: " . implode("\n", $output));
}
$crt = file_get_contents($crtPath);
unlink($crtPath);
unlink($csrPath);
return $crt;
}
/**
* Signs a client certificate and returns the signed certificate
* @param string $csr
* @return string
* @throws \Exception
*/
public function signServerKey($csr)
{
/** @var Core $core */
$core = $this->get('core');
$csrPath = tempnam(sys_get_temp_dir(), '0.');
$crtPath = tempnam(sys_get_temp_dir(), '0.');
file_put_contents($csrPath, $csr);
exec(escapeshellcmd($core->getBaseDir() . '/bin/sign-server-csr') . ' ' . escapeshellarg($csrPath) . ' ' . escapeshellarg($crtPath) . ' 2>&1', $output, $exitCode);
if ($exitCode !== 0) {
throw new \Exception("Failed signing CSR: " . implode("\n", $output));
}
$crt = file_get_contents($crtPath);
unlink($crtPath);
unlink($csrPath);
return $crt;
}
/**
* @param string $csr
* @throws \Exception
*/
public function getCommonNameFromCsr($csr)
{
$subject = openssl_csr_get_subject($csr);
if ($subject === false) {
throw new \Exception("Failed to read CSR: " . $this->getOpenSslError());
}
return $subject["CN"];
}
/**
* @param string $certificate
* @throws \Exception
*/
public function revoke($certificate)
{
/** @var Core $core */
$core = $this->get('core');
$crtPath = tempnam(sys_get_temp_dir(), '0.');
file_put_contents($crtPath, $certificate);
exec(escapeshellcmd($core->getBaseDir() . '/bin/revoke-cert') . ' ' . escapeshellarg($crtPath) . ' 2>&1', $output, $exitCode);
if ($exitCode !== 0) {
throw new \Exception("Failed signing CSR: " . implode("\n", $output));
}
unlink($crtPath);
}
/**
* @param string $pubKey
* @return string
* @throws \Exception
*/
public function getFingerprintFromPublicKey($pubKey)
{
/** @var Core $core */
$core = $this->get('core');
$pubPath = tempnam(sys_get_temp_dir(), '0.');
file_put_contents($pubPath, $pubKey);
exec(escapeshellcmd($core->getBaseDir() . '/bin/get-fingerprint') . ' ' . escapeshellarg($pubPath) . ' 2>&1', $output, $exitCode);
if ($exitCode !== 0) {
throw new \Exception("Failed getting fingerprint from public key: " . implode("\n", $output));
}
unlink($pubPath);
return $output[0];
}
public function verify($data, $signature, $publicKey)
{
$publicKeyResource = openssl_pkey_get_public($publicKey);
$result = openssl_verify($data, $signature, $publicKeyResource);
if ($result === 1) {
return true;
} else if ($result === 0) {
return false;
}
throw new \Exception("Verify failed: " . $this->getOpenSslError());
}
public function signWithCA($data) {
$privateKeyPlain = $this->getPrivateKey();
$privateKey = openssl_get_privatekey($privateKeyPlain);
$result = openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256);
if ($result) {
return $signature;
}
throw new \Exception("Signing failed: " . $this->getOpenSslError());
}
}