git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@5107 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
223 lines
6.0 KiB
PHP
223 lines
6.0 KiB
PHP
<?php
|
|
/** DomFirewall
|
|
* @package domfirewall
|
|
* @author Dominique Fournier <dominique@fournier38.fr>
|
|
*/
|
|
|
|
/** An certificate authority
|
|
*/
|
|
class certificationauthority
|
|
{
|
|
// PROPERTIES
|
|
/** The opensslCnfPath file
|
|
*/
|
|
private $opensslCnfPath;
|
|
|
|
/** The CA public cert
|
|
*/
|
|
private $caCert = "";
|
|
/** The CA private key
|
|
*/
|
|
private $caKey = "";
|
|
|
|
/** The user private key resource
|
|
*/
|
|
private $privateKey;
|
|
|
|
/** The configuration arguments
|
|
*/
|
|
private $configargs = array ();
|
|
|
|
/** Check if /usr/bin/openssl is available */
|
|
public function __construct ()
|
|
// {{{
|
|
{
|
|
if (! function_exists ("openssl_csr_new"))
|
|
throw new \Exception (_("No openssl support in PHP"),
|
|
500);
|
|
$this->opensslCnfPath = tempnam ("/tmp", "openssl-");
|
|
file_put_contents ($this->opensslCnfPath,
|
|
'HOME = .
|
|
RANDFILE = $ENV::HOME/.rnd
|
|
|
|
[ req ]
|
|
distinguished_name = req_distinguished_name
|
|
|
|
[ req_distinguished_name ]
|
|
|
|
[ v3_req ]
|
|
basicConstraints = CA:FALSE
|
|
keyUsage = digitalSignature, keyEncipherment
|
|
extendedKeyUsage = serverAuth, clientAuth
|
|
|
|
[ v3_ca ]
|
|
subjectKeyIdentifier=hash
|
|
authorityKeyIdentifier=keyid:always,issuer
|
|
basicConstraints = critical,CA:true
|
|
keyUsage = cRLSign, keyCertSign
|
|
');
|
|
$this->configargs = array (
|
|
"config" => $this->opensslCnfPath,
|
|
"digest_alg" => "sha256WithRSAEncryption",
|
|
"private_key_bits" => 4096,
|
|
);
|
|
}
|
|
// }}}
|
|
|
|
public function __destruct ()
|
|
// {{{
|
|
{
|
|
if (file_exists ($this->opensslCnfPath))
|
|
unlink ($this->opensslCnfPath);
|
|
}
|
|
// }}}
|
|
|
|
/** Create the pair key/cert for authority
|
|
* @param string $countryName Country name (like FR)
|
|
* @param string $organizationName Name of organization
|
|
* @param string $commonName Common name of authority
|
|
* @param integer|null $days The number of days of validity of the CA (3650
|
|
* by default)
|
|
* @return $this
|
|
*/
|
|
public function createCA ($countryName, $organizationName, $commonName,
|
|
$days = 3650)
|
|
// {{{
|
|
{
|
|
$req_key = openssl_pkey_new (array (
|
|
"config" => $this->opensslCnfPath,
|
|
"private_key_bits" => 4096,
|
|
"private_key_type" => OPENSSL_KEYTYPE_RSA,
|
|
));
|
|
$dn = array (
|
|
"countryName" => $countryName,
|
|
"organizationName" => $organizationName,
|
|
"commonName" => $commonName,
|
|
);
|
|
$this->configargs["x509_extensions"] = "v3_ca";
|
|
// x509_extensions must be defined in /etc/ssl/openssl.cnf
|
|
$req_csr = openssl_csr_new ($dn, $req_key, $this->configargs);
|
|
$req_cert = openssl_csr_sign ($req_csr, NULL, $req_key, $days,
|
|
$this->configargs);
|
|
openssl_x509_export ($req_cert, $this->caCert);
|
|
openssl_pkey_export ($req_key, $this->caKey);
|
|
return $this;
|
|
}
|
|
// }}}
|
|
|
|
/** Get/Set the ca cert
|
|
* @param string|null The CA cert to get/set
|
|
* @return the CA if get in PEM, $this if set
|
|
*/
|
|
public function caCert ($caCert = null)
|
|
// {{{
|
|
{
|
|
if ($caCert === null)
|
|
return $this->caCert;
|
|
if (! is_string ($caCert))
|
|
throw new \Exception ("AC : Invalid caCert provided : not a string", 500);
|
|
$this->caCert = $caCert;
|
|
return $this;
|
|
}
|
|
// }}}
|
|
|
|
/** Get/Set the ca key
|
|
* @param string|null The CA key to get/set
|
|
* @return the CA if get, $this if set
|
|
*/
|
|
public function caKey ($caKey = null)
|
|
// {{{
|
|
{
|
|
if ($caKey === null)
|
|
return $this->caKey;
|
|
if (! is_string ($caKey))
|
|
throw new \Exception ("AC : invalid caKey provided : not a string", 500);
|
|
$this->caKey = $caKey;
|
|
return $this;
|
|
}
|
|
// }}}
|
|
|
|
/** Create a private key
|
|
* @return $this;
|
|
*/
|
|
public function createPrivateKey ()
|
|
// {{{
|
|
{
|
|
$this->privateKey = openssl_pkey_new (array (
|
|
"config" => $this->opensslCnfPath,
|
|
"private_key_bits" => 4096,
|
|
"private_key_type" => OPENSSL_KEYTYPE_RSA,
|
|
));
|
|
return $this;
|
|
}
|
|
// }}}
|
|
|
|
/** Get in PEM/Set the private key
|
|
* @param string|null The private key to use
|
|
* @return the privatekey if get in PEM, $this if set
|
|
*/
|
|
public function privateKey ($privateKey = null)
|
|
// {{{
|
|
{
|
|
if ($privateKey === null)
|
|
{
|
|
openssl_pkey_export($this->privateKey, $out);
|
|
return $out;
|
|
}
|
|
if (! is_string ($privateKey))
|
|
throw new \Exception ("AC : invalid privateKey provided : not a string",
|
|
500);
|
|
$this->privateKey = openssl_pkey_get_private ($privateKey);
|
|
return $this;
|
|
}
|
|
// }}}
|
|
|
|
/** Create a CSR
|
|
* @param string $countryName Country name (like FR)
|
|
* @param string $organizationName Name of organization
|
|
* @param string $commonName Common name of authority
|
|
* @return the CSR created in PEM
|
|
*/
|
|
public function createCSR ($countryName, $organizationName, $commonName)
|
|
// {{{
|
|
{
|
|
if ($this->privateKey === null)
|
|
$this->createPrivateKey ();
|
|
$dn = array (
|
|
"countryName" => $countryName,
|
|
"organizationName" => $organizationName,
|
|
"commonName" => $commonName,
|
|
);
|
|
$this->configargs["x509_extensions"] = "v3_req";
|
|
$req_csr = openssl_csr_new ($dn, $this->privateKey, $this->configargs);
|
|
if ($req_csr === false)
|
|
throw new \Exception ("CA : Can not generate a CSR", 500);
|
|
openssl_csr_export ($req_csr, $out);
|
|
return $out;
|
|
}
|
|
// }}}
|
|
|
|
/** Sign a CSR with an CA cert and key and return the signed certificate in
|
|
* PEM mode
|
|
* The caCert and caKey must be defined
|
|
* @param string $csr The CSR to sign
|
|
* @param string $caCert The CA Certificate
|
|
* @param string $caKey The CA private key
|
|
* @param integer|null $days The number of days of validity (365 by default)
|
|
* @return the signed certificate in PEM
|
|
*/
|
|
public function signCSR ($csr, $caCert, $caKey, $days = 365)
|
|
// {{{
|
|
{
|
|
$this->configargs["x509_extensions"] = "v3_req";
|
|
$usercert = openssl_csr_sign ($csr, $caCert, $caKey, $days,
|
|
$this->configargs, date ("YmdHis"));
|
|
if ($usercert === false)
|
|
throw new \Exception ("Can not create certificate : " .
|
|
openssl_error_string (), 500);
|
|
openssl_x509_export($usercert, $certout);
|
|
return $certout;
|
|
}
|
|
// }}}
|
|
}
|