forked from zer.ooo/web
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
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());
|
|
}
|
|
} |