CertificateGenerator.inc 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <?php
  2. class CertificateGenerator
  3. {
  4. const CONFIG = __DIR__. DIRECTORY_SEPARATOR . 'openssl.cnf';
  5. /** @var resource */
  6. private $ca;
  7. /** @var resource */
  8. private $caKey;
  9. /** @var resource|null */
  10. private $lastCert;
  11. /** @var resource|null */
  12. private $lastKey;
  13. public function __construct()
  14. {
  15. if (!extension_loaded('openssl')) {
  16. throw new RuntimeException(
  17. 'openssl extension must be loaded to generate certificates'
  18. );
  19. }
  20. $this->generateCa();
  21. }
  22. /**
  23. * @param int|null $keyLength
  24. * @return resource
  25. */
  26. private static function generateKey($keyLength = null)
  27. {
  28. if (null === $keyLength) {
  29. $keyLength = 2048;
  30. }
  31. return openssl_pkey_new([
  32. 'private_key_bits' => $keyLength,
  33. 'private_key_type' => OPENSSL_KEYTYPE_RSA,
  34. 'encrypt_key' => false,
  35. ]);
  36. }
  37. private function generateCa()
  38. {
  39. $this->caKey = self::generateKey();
  40. $dn = [
  41. 'countryName' => 'GB',
  42. 'stateOrProvinceName' => 'Berkshire',
  43. 'localityName' => 'Newbury',
  44. 'organizationName' => 'Example Certificate Authority',
  45. 'commonName' => 'CA for PHP Tests'
  46. ];
  47. $this->ca = openssl_csr_sign(
  48. openssl_csr_new(
  49. $dn,
  50. $this->caKey,
  51. [
  52. 'x509_extensions' => 'v3_ca',
  53. 'config' => self::CONFIG,
  54. ]
  55. ),
  56. null,
  57. $this->caKey,
  58. 2
  59. );
  60. }
  61. public function getCaCert()
  62. {
  63. $output = '';
  64. openssl_x509_export($this->ca, $output);
  65. return $output;
  66. }
  67. public function saveCaCert($file)
  68. {
  69. openssl_x509_export_to_file($this->ca, $file);
  70. }
  71. public function saveNewCertAsFileWithKey($commonNameForCert, $file, $keyLength = null)
  72. {
  73. $dn = [
  74. 'countryName' => 'BY',
  75. 'stateOrProvinceName' => 'Minsk',
  76. 'localityName' => 'Minsk',
  77. 'organizationName' => 'Example Org',
  78. 'commonName' => $commonNameForCert,
  79. ];
  80. $this->lastKey = self::generateKey($keyLength);
  81. $this->lastCert = openssl_csr_sign(
  82. openssl_csr_new($dn, $this->lastKey, ['req_extensions' => 'v3_req']),
  83. $this->ca,
  84. $this->caKey,
  85. 2
  86. );
  87. $certText = '';
  88. openssl_x509_export($this->lastCert, $certText);
  89. $keyText = '';
  90. openssl_pkey_export($this->lastKey, $keyText);
  91. file_put_contents($file, $certText . PHP_EOL . $keyText);
  92. }
  93. public function getCertDigest($algo)
  94. {
  95. return openssl_x509_fingerprint($this->lastCert, $algo);
  96. }
  97. }