Add certification authority support
git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@5107 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
This commit is contained in:
222
certificationauthority.php
Normal file
222
certificationauthority.php
Normal file
@@ -0,0 +1,222 @@
|
||||
<?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;
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
Reference in New Issue
Block a user