Initial commit
This commit is contained in:
commit
384646df40
|
@ -0,0 +1,12 @@
|
||||||
|
vendor/
|
||||||
|
composer.lock
|
||||||
|
*~
|
||||||
|
.php_cs.cache
|
||||||
|
data/
|
||||||
|
*.crt
|
||||||
|
*.csr
|
||||||
|
*.key
|
||||||
|
*.pub
|
||||||
|
.idea
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$header = <<<EOF
|
||||||
|
Self-Sign Cert
|
||||||
|
Copyright (C) 2017 http://blog.rewiv.com eric@rewiv.com
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
EOF;
|
||||||
|
|
||||||
|
|
||||||
|
return PhpCsFixer\Config::create()
|
||||||
|
->setRiskyAllowed(true)
|
||||||
|
->setRules(
|
||||||
|
[
|
||||||
|
'@Symfony' => true,
|
||||||
|
'header_comment' => ['header' => $header],
|
||||||
|
'ordered_class_elements' => true,
|
||||||
|
'ordered_imports' => true,
|
||||||
|
'no_mixed_echo_print' => ['use' => 'print'],
|
||||||
|
'strict_param' => true,
|
||||||
|
'strict_comparison' => true,
|
||||||
|
'single_import_per_statement' => false,
|
||||||
|
'phpdoc_order' => true,
|
||||||
|
'array_syntax' => ['syntax' => 'short'],
|
||||||
|
'phpdoc_add_missing_param_annotation' => true,
|
||||||
|
'psr4' => true,
|
||||||
|
'phpdoc_var_without_name' => false,
|
||||||
|
'no_extra_consecutive_blank_lines' => [
|
||||||
|
'break',
|
||||||
|
'continue',
|
||||||
|
'extra',
|
||||||
|
'return',
|
||||||
|
'throw',
|
||||||
|
'parenthesis_brace_block',
|
||||||
|
'square_brace_block',
|
||||||
|
'curly_brace_block'
|
||||||
|
],
|
||||||
|
]
|
||||||
|
)->setFinder(
|
||||||
|
PhpCsFixer\Finder::create()
|
||||||
|
->ignoreDotFiles(true)
|
||||||
|
->ignoreVCS(true)
|
||||||
|
->name('*.php')
|
||||||
|
->in([
|
||||||
|
__DIR__,
|
||||||
|
'src',
|
||||||
|
'bin',
|
||||||
|
])
|
||||||
|
);
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Self-Sign Cert
|
||||||
|
* Copyright (C) 2017 http://blog.rewiv.com eric@rewiv.com
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sikofitt\Console\Command\Tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class SignCertCommandTest extends TestCase
|
||||||
|
{
|
||||||
|
// TODO: Add tests
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"name": "sikofitt/self-sign-cert",
|
||||||
|
"description": "Easy self signed certs",
|
||||||
|
"type": "project",
|
||||||
|
"require": {
|
||||||
|
"php":">=7.1",
|
||||||
|
"roave/security-advisories": "dev-master",
|
||||||
|
"egulias/email-validator": "^2.1",
|
||||||
|
"mledoze/countries": "^1.8",
|
||||||
|
"phpseclib/phpseclib": "^2.0",
|
||||||
|
"respect/validation": "^1.1",
|
||||||
|
"symfony/console": "^3.2",
|
||||||
|
"webmozart/json": "^1.2"
|
||||||
|
},
|
||||||
|
"license": "GPL-3.0",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "R. Eric Wheeler",
|
||||||
|
"email": "sikofitt@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Sikofitt\\":"src/Sikofitt/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"Sikofitt\\Tests\\":"Tests/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"sort-packages": true
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "^2.1",
|
||||||
|
"phpunit/phpunit": "^6.0",
|
||||||
|
"symfony/var-dumper": "^3.2"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Self-Sign Cert
|
||||||
|
* Copyright (C) 2017 http://blog.rewiv.com eric@rewiv.com
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
require __DIR__.'/vendor/autoload.php';
|
||||||
|
|
||||||
|
$application = new \Symfony\Component\Console\Application();
|
||||||
|
|
||||||
|
$dataDir = dirname(__DIR__.'/vendor/mledoze/countries/dist/countries.json');
|
||||||
|
|
||||||
|
$application->add(new Sikofitt\Console\Command\SignCertCommand(__DIR__));
|
||||||
|
$application->add(new MLD\Console\Command\ExportCommand($dataDir.'/countries.json', __DIR__.'/data'));
|
||||||
|
$application->run();
|
|
@ -0,0 +1,385 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Self-Sign Cert
|
||||||
|
* Copyright (C) 2017 http://blog.rewiv.com eric@rewiv.com
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sikofitt\Console\Command;
|
||||||
|
|
||||||
|
use Egulias\EmailValidator\EmailValidator;
|
||||||
|
use Egulias\EmailValidator\Validation\DNSCheckValidation;
|
||||||
|
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
|
||||||
|
use Egulias\EmailValidator\Validation\RFCValidation;
|
||||||
|
use Egulias\EmailValidator\Validation\SpoofCheckValidation;
|
||||||
|
use phpseclib\Crypt\RSA;
|
||||||
|
use phpseclib\File\X509;
|
||||||
|
use Sikofitt\PHPSecLib\Exception\PhpSecLibErrorToException;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Exception\InvalidArgumentException;
|
||||||
|
use Symfony\Component\Console\Exception\InvalidOptionException;
|
||||||
|
use Symfony\Component\Console\Exception\LogicException;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||||
|
use Symfony\Component\Console\Question\Question;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
use Webmozart\Json\JsonDecoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SignCertCommand.
|
||||||
|
*/
|
||||||
|
class SignCertCommand extends Command
|
||||||
|
{
|
||||||
|
private $distinguishedName;
|
||||||
|
private $rootDir;
|
||||||
|
private $digestAlgo;
|
||||||
|
private $privateKeyBits;
|
||||||
|
private $domains = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SignCertCommand constructor.
|
||||||
|
*
|
||||||
|
* @param string $rootDir
|
||||||
|
*
|
||||||
|
* @throws LogicException
|
||||||
|
*/
|
||||||
|
public function __construct(string $rootDir)
|
||||||
|
{
|
||||||
|
parent::__construct(null);
|
||||||
|
$this->rootDir = $rootDir;
|
||||||
|
set_error_handler([$this, 'errorHandler']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws PhpSecLibErrorToException
|
||||||
|
*/
|
||||||
|
public static function errorHandler()
|
||||||
|
{
|
||||||
|
[$errorNumber, $errorString, $errorFile, $errorLine] = func_get_args();
|
||||||
|
|
||||||
|
$message = sprintf(
|
||||||
|
"%s\nError # %s\nFile : %s\nLine : %s",
|
||||||
|
$errorString,
|
||||||
|
$errorNumber,
|
||||||
|
$errorFile,
|
||||||
|
$errorLine
|
||||||
|
);
|
||||||
|
throw new PhpSecLibErrorToException($message, $errorNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function configure(): void
|
||||||
|
{
|
||||||
|
$hostname = gethostname();
|
||||||
|
$this->setName('sign')
|
||||||
|
->setAliases(['cert', 'sign:cert'])
|
||||||
|
->setDescription('Self sign certificates easily.')
|
||||||
|
->addOption(
|
||||||
|
'years',
|
||||||
|
'y',
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'Number of years for the certificate',
|
||||||
|
10
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'csrname',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'Signing request filename.',
|
||||||
|
$hostname.'.csr'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'keyname',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'Private key filename.',
|
||||||
|
$hostname.'.key'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'pkeyname',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'Public key filename.',
|
||||||
|
$hostname.'.pub'
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'certname',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'Certificate filename.',
|
||||||
|
$hostname.'.crt'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param InputInterface $input
|
||||||
|
* @param OutputInterface $output
|
||||||
|
*
|
||||||
|
* @throws InvalidOptionException
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
* @throws LogicException
|
||||||
|
*/
|
||||||
|
public function interact(
|
||||||
|
InputInterface $input,
|
||||||
|
OutputInterface $output
|
||||||
|
): void {
|
||||||
|
$jsonDecoder = new JsonDecoder();
|
||||||
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
try {
|
||||||
|
$countries = (array) $jsonDecoder->decodeFile($this->rootDir.'/data/countries.json');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new LogicException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
$choices = [];
|
||||||
|
|
||||||
|
foreach ($countries as $country) {
|
||||||
|
/** @var array $altSpellings */
|
||||||
|
$altSpellings = (array) $country->altSpellings;
|
||||||
|
foreach ($altSpellings as $altSpelling) {
|
||||||
|
if (preg_match('/\s/', $altSpelling)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$twoLetterCode = $altSpelling; //substr($altSpelling, 0, 3);
|
||||||
|
$choices[mb_strtolower($twoLetterCode)] = mb_strtoupper($twoLetterCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$countryQuestion = new Question('Country Name');
|
||||||
|
$countryQuestion->setAutocompleterValues($choices);
|
||||||
|
$countryQuestion->setNormalizer(function ($value) {
|
||||||
|
return mb_strtoupper(trim($value));
|
||||||
|
});
|
||||||
|
|
||||||
|
$countryQuestion->setValidator(function ($value) use ($choices) {
|
||||||
|
if (false === in_array(mb_strtoupper($value), $choices, true)) {
|
||||||
|
throw new InvalidOptionException($value.' is not a valid country choice.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
});
|
||||||
|
$countryName = $io->askQuestion($countryQuestion);
|
||||||
|
$stateOrProvinceName = $io->ask('State or Province Name');
|
||||||
|
$localityName = $io->ask('Locality Name');
|
||||||
|
$organizationName = $io->ask('Organization Name');
|
||||||
|
$organizationalUnitName = $io->ask('Organizational Unit Name');
|
||||||
|
$commonName = $io->ask('Common Name', gethostname(), function ($value) {
|
||||||
|
if (null === $value) {
|
||||||
|
return gethostname();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
});
|
||||||
|
$emailAddress = $io->ask('Email address (Optional)', null,
|
||||||
|
function ($value) use ($io) {
|
||||||
|
if (null === $value) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
$emailValidator = new EmailValidator();
|
||||||
|
$validators = new MultipleValidationWithAnd([
|
||||||
|
new RFCValidation(),
|
||||||
|
new SpoofCheckValidation(),
|
||||||
|
new DNSCheckValidation(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (true === $emailValidator->isValid($value, $validators)) {
|
||||||
|
if ($emailValidator->hasWarnings()) {
|
||||||
|
$io->warning($emailValidator->getWarnings());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidOptionException($emailValidator->getError()->getMessage());
|
||||||
|
});
|
||||||
|
|
||||||
|
$signingAlgos = [
|
||||||
|
'md2' => 'md2',
|
||||||
|
'md5' => 'md5',
|
||||||
|
'sha1' => 'sha1',
|
||||||
|
'sha256' => 'sha256',
|
||||||
|
'sha384' => 'sha384',
|
||||||
|
'sha512' => 'sha512',
|
||||||
|
];
|
||||||
|
$this->domains = [$commonName];
|
||||||
|
$domainQuestion = new Question('Domains (hit enter on a blank line to stop adding',
|
||||||
|
false);
|
||||||
|
$domainQuestion->setValidator(function ($value) {
|
||||||
|
if (false !== $value) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
while (false !== $domain = $io->askQuestion($domainQuestion)) {
|
||||||
|
$this->domains[] = $domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
$digestAlgoQuestion = new ChoiceQuestion('Digest Method', $signingAlgos,
|
||||||
|
'sha512');
|
||||||
|
|
||||||
|
$digestAlgoQuestion->setValidator(function ($value) use ($signingAlgos) {
|
||||||
|
if (false === in_array($value, $signingAlgos,
|
||||||
|
true)
|
||||||
|
) {
|
||||||
|
throw new InvalidOptionException('Invalid digest algorithm : '.$value.'.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
});
|
||||||
|
$digestAlgoQuestion->setAutocompleterValues($signingAlgos);
|
||||||
|
$privateKeyBitsQuestion = new Question('Private key bits', 2048);
|
||||||
|
$privateKeyBitsQuestion->setNormalizer(function ($value) {
|
||||||
|
return (int) $value;
|
||||||
|
});
|
||||||
|
$privateKeyBitsQuestion->setValidator(function ($value) {
|
||||||
|
if ($value < 384) {
|
||||||
|
throw new InvalidOptionException('Private key bytes should be greater than 384.');
|
||||||
|
}
|
||||||
|
if (false === $this->validateBits($value, $this->digestAlgo)) {
|
||||||
|
throw new InvalidOptionException('Not enough bits for algorithm '.$this->digestAlgo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
});
|
||||||
|
$this->digestAlgo = $io->askQuestion($digestAlgoQuestion);
|
||||||
|
$this->privateKeyBits = $io->askQuestion($privateKeyBitsQuestion);
|
||||||
|
|
||||||
|
$this->distinguishedName = [
|
||||||
|
'countryName' => $countryName,
|
||||||
|
'stateOrProvinceName' => $stateOrProvinceName,
|
||||||
|
'localityName' => $localityName,
|
||||||
|
'organizationName' => $organizationName,
|
||||||
|
'organizationalUnitName' => $organizationalUnitName,
|
||||||
|
'commonName' => $commonName,
|
||||||
|
];
|
||||||
|
if (null !== $emailAddress) {
|
||||||
|
$this->distinguishedName['emailAddress'] = $emailAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param InputInterface $input
|
||||||
|
* @param OutputInterface $output
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function execute(
|
||||||
|
InputInterface $input,
|
||||||
|
OutputInterface $output
|
||||||
|
): void {
|
||||||
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
if ($this->privateKeyBits > 4096) {
|
||||||
|
$io->warning('Please wait, this could take awhile with '.$this->privateKeyBits.' bits.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$years = $input->getOption('years');
|
||||||
|
$privateKeyObject = new RSA();
|
||||||
|
$privateKeyObject->setEncryptionMode(RSA::ENCRYPTION_OAEP);
|
||||||
|
$privateKeyObject->setHash($this->digestAlgo);
|
||||||
|
$privateKeyObject->setMGFHash($this->digestAlgo);
|
||||||
|
$privateKeyObject->setSignatureMode(RSA::SIGNATURE_PKCS1);
|
||||||
|
$privateKeyParts = $privateKeyObject->createKey($this->privateKeyBits);
|
||||||
|
$privateKey = $privateKeyParts['privatekey'];
|
||||||
|
$publicKey = $privateKeyParts['publickey'];
|
||||||
|
$privateKeyObject->loadKey($privateKey);
|
||||||
|
|
||||||
|
$pubKey = new RSA();
|
||||||
|
$pubKey->loadKey($publicKey);
|
||||||
|
$pubKey->setPublicKey();
|
||||||
|
$subject = new X509();
|
||||||
|
$subject->setStartDate('now');
|
||||||
|
$subject->setEndDate('now +'.$years.' years');
|
||||||
|
$subject->setDN($this->distinguishedName, true);
|
||||||
|
if (count($this->domains) > 1) {
|
||||||
|
call_user_func_array([$subject, 'setDomain'], $this->domains);
|
||||||
|
}
|
||||||
|
$subject->setPublicKey($pubKey);
|
||||||
|
|
||||||
|
$issuer = new X509();
|
||||||
|
$issuer->setStartDate('now');
|
||||||
|
$issuer->setEndDate('now +'.$years.' years');
|
||||||
|
$issuer->setPrivateKey($privateKeyObject);
|
||||||
|
$issuer->setDN($subject->getDN());
|
||||||
|
|
||||||
|
$x509 = new X509();
|
||||||
|
$x509->setStartDate('now');
|
||||||
|
$x509->setEndDate('now +'.$years.' years');
|
||||||
|
$csr = $issuer->signCSR($this->prefixHash($this->digestAlgo));
|
||||||
|
|
||||||
|
$result = $x509->sign($issuer, $subject,
|
||||||
|
$this->prefixHash($this->digestAlgo));
|
||||||
|
|
||||||
|
file_put_contents($input->getOption('keyname'), $privateKeyObject->getPrivateKey());
|
||||||
|
file_put_contents($input->getOption('pkeyname'), $privateKeyObject->getPublicKey());
|
||||||
|
file_put_contents($input->getOption('csrname'), $x509->saveCSR($csr));
|
||||||
|
file_put_contents($input->getOption('certname'), $x509->saveX509($result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $bits
|
||||||
|
* @param string $algo
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function validateBits(int $bits, string $algo): bool
|
||||||
|
{
|
||||||
|
// see http://tools.ietf.org/html/rfc3447#page-43
|
||||||
|
switch ($algo) {
|
||||||
|
case 'sha256':
|
||||||
|
if ($bits < 496) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case 'sha384':
|
||||||
|
if ($bits < 624) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case 'sha512':
|
||||||
|
if ($bits < 752) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $hash
|
||||||
|
* The hash to prefix
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The hash prefixed with 'WithRSAEncryption'
|
||||||
|
*/
|
||||||
|
private function prefixHash(string $hash): string
|
||||||
|
{
|
||||||
|
return sprintf('%sWithRSAEncryption', $hash);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Self-Sign Cert
|
||||||
|
* Copyright (C) 2017 http://blog.rewiv.com eric@rewiv.com
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sikofitt\PHPSecLib\Exception;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PhpSecLibErrorToException.
|
||||||
|
*/
|
||||||
|
class PhpSecLibErrorToException extends \Exception implements ExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
Loading…
Reference in New Issue