From 99c17660d816cb93b4fce506e2c77ce77d2636f5 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 25 Jan 2024 07:46:42 +1200 Subject: [PATCH] Initial --- .editorconfig | 6 + .gitignore | 22 ++ cmpOpenSSLClass.php | 37 ++ cmpOpenSSLTests.php | 83 ++++ cmpOpenSSLTrait.php | 940 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1088 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 cmpOpenSSLClass.php create mode 100644 cmpOpenSSLTests.php create mode 100644 cmpOpenSSLTrait.php diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c651587 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,6 @@ + + + [*] + end_of_line = lf + indent_style = tab + tab_width = 4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..902374d --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +**/*_ +**/.#* +**/0* +**/1* +**/2* +**/3* +**/4* +**/5* +**/6* +**/7* +**/8* +**/9* + +**/*.log* +**/*log +**/LOG* + +cache/** +data/** +old/** +outer/** +secret/** diff --git a/cmpOpenSSLClass.php b/cmpOpenSSLClass.php new file mode 100644 index 0000000..f03f586 --- /dev/null +++ b/cmpOpenSSLClass.php @@ -0,0 +1,37 @@ +getMessage() . "\n"; + return $r; + } + + echo "Error: Unknown\n"; + return $r; + } + + function d($s) { + echo "debug: $s\n"; + } + + // END CLASS + } diff --git a/cmpOpenSSLTests.php b/cmpOpenSSLTests.php new file mode 100644 index 0000000..2bc2db1 --- /dev/null +++ b/cmpOpenSSLTests.php @@ -0,0 +1,83 @@ +cmpOpenSslGenDh(); + + var_export($out); + + exit; + } + + if(1) { + $parm = array( + "days" => 3650 , + "outfile" => "test-ca-01" , + "commonName" => "test-ca-01" , + "stateOrProvinceName" => "MSK" , + "localityName" => "MSK" , + "emailAddress" => "it@example.ru" , + "organizationName" => "TEST" , + "organizationalUnitName" => "TEST-OIT" , + ); + + $out = array(); + + $x->createCA($parm, $out); + + var_export($out); + + //exit; + } + + if(1) { + $parm = array( + "days" => 3650 , + "outfile" => "test-srv-01" , + "commonName" => "test-srv-01" , + "stateOrProvinceName" => "MSK" , + "localityName" => "MSK" , + "emailAddress" => "it@example.ru" , + "organizationName" => "TEST" , + "organizationalUnitName" => "TEST-OIT" , + ); + + $x->loadFromFileCACrt("test-ca-01.crt"); + $x->loadFromFileCAPrv("test-ca-01.prv"); + + $out = array(); + + $x->createServer($parm, $out); + + var_export($out); + + //exit; + } + + if(1) { + $parm = array( + "days" => 365 , + "outfile" => "test-cli-cli01" , + "commonName" => "test-cli-cli01" , + "stateOrProvinceName" => "MSK" , + "localityName" => "MSK" , + "emailAddress" => "it@example.ru" , + "organizationName" => "TEST" , + "organizationalUnitName" => "TEST-OIT" , + ); + + $x->loadFromFileCACrt("test-ca-01.crt"); + $x->loadFromFileCAPrv("test-ca-01.prv"); + + $out = array(); + + $x->createClient($parm, $out); + + var_export($out); + + //exit; + } + diff --git a/cmpOpenSSLTrait.php b/cmpOpenSSLTrait.php new file mode 100644 index 0000000..0311794 --- /dev/null +++ b/cmpOpenSSLTrait.php @@ -0,0 +1,940 @@ +ver; + + $this->cmpOpenSslConf = array ( + "GLOBAL" => array ( + "oid_section" => "OIDs", + ), + "OIDs" => array ( + "cmpExtOid" => "1.2.3.20190828", + "certificateTemplateName" => "\${cmpExtOid}.1", + ), + "ca" => array ( + "default_ca" => "cmp_ca", + ), + "cmp_ca" => array ( + "dir" => ".", + "certs" => "\$dir", + "crl_dir" => "\$dir}", + "database" => "\$dir/index.txt", + "new_certs_dir" => "\$dir", + "serial" => "\$dir/serial", + "crl" => "\$dir/crl.pem", + "certificate" => "\$dir/ca.crt", + "private_key" => "\$dir/ca.key", + "RANDFILE" => "\$dir/.rand", + "x509_extensions" => "cmp_x509_ext_basic", + "crl_extensions" => "cmp_crl_ext", + "default_days" => 3650, + "default_crl_days" => 30, + "default_md" => "sha256", + "preserve" => "no", + "policy" => "cmp_policy_anything", + ), + "cmp_policy_anything" => array ( + "countryName" => "optional", + "stateOrProvinceName" => "optional", + "localityName" => "optional", + "organizationName" => "optional", + "organizationalUnitName" => "optional", + "commonName" => "supplied", + "name" => "optional", + "emailAddress" => "optional", + ), + "req" => array ( + "default_bits" => 2048, + "default_keyfile" => "privkey.pem", + "default_md" => "sha256", + "distinguished_name" => "cmp_dst_ext", + "x509_extensions" => "cmp_x509_ext_rsa", + "req_extensions" => "cmp_req_ext_v3", + ), + "cmp_dst_ext" => array ( + "commonName" => "Common Name (eg: your user, host, or server name)", + "commonName_max" => 64, + "commonName_default" => $claver . "-commonName_default", + // "certificateTemplateName" => $claver , // "-certificateTemplateName", + "certificateTemplateName_default" => $claver , + ), + "cmp_req_ext_v3" => array ( + "certificateTemplateName" => "ASN1:PRINTABLESTRING:CustomUserOffline", + ), + "cmp_org" => array ( + "countryName" => "Country Name (2 letter code)", + "countryName_default" => "RU", + "countryName_min" => 2, + "countryName_max" => 2, + + "stateOrProvinceName" => "State or Province Name (full name)", + "stateOrProvinceName_default" => $claver . "-stateOrProvinceName_default", + + "localityName" => "Locality Name (eg, city)", + "localityName_default" => $claver . "-localityName_default", + + "organizationName" => "Organization Name (eg, company)", + "organizationName_default" => $claver . "-organizationName_default", + + "organizationalUnitName" => "Organizational Unit Name (eg, section)", + "organizationalUnitName_default" => $claver . "-organizationalUnitName_default", + + "emailAddress" => "Email Address", + "emailAddress_default" => $claver . "@example.org", + "emailAddress_max" => 64, + ), + "cmp_crl_ext" => array ( + "authorityKeyIdentifier" => "keyid:always,issuer:always", + ), + "cmp_x509_ext_basic" => array ( + "basicConstraints" => "CA:FALSE", + "subjectKeyIdentifier" => "hash", + "authorityKeyIdentifier" => "keyid,issuer:always", + ), + "cmp_x509_ext_rsa" => array ( + "subjectKeyIdentifier" => "hash", + "authorityKeyIdentifier" => "keyid:always,issuer:always", + "basicConstraints" => "CA:true", + "keyUsage" => "cRLSign, keyCertSign", + ), + "cmp_x509_ext_srv" => array ( + "basicConstraints" => "CA:FALSE", + "nsCertType" => "server", + "nsComment" => "\"OpenSSL Generated Server Certificate\"", + "subjectKeyIdentifier" => "hash", + "authorityKeyIdentifier" => "keyid,issuer:always", + "extendedKeyUsage" => "serverAuth", + "keyUsage" => "digitalSignature, keyEncipherment", + ), + "cmp_x509_ext_cli" => array ( + "basicConstraints" => "CA:FALSE", + "nsCertType" => "client", + "nsComment" => "\"OpenSSL Generated Client Certificate\"", + "subjectKeyIdentifier" => "hash", + "authorityKeyIdentifier" => "keyid,issuer", + "keyUsage" => "critical, nonRepudiation, digitalSignature, keyEncipherment", + "extendedKeyUsage" => "clientAuth", + ), + ); + + + return true; + } + + function cmpOpenSslConfTemp() { + $a = array(); + + if(!isset($this->cmpOpenSslConf["GLOBAL"])) { + $this->cmpOpenSslConfSetDefault(); + } + + if(!isset($this->cmpOpenSslConf["GLOBAL"])) { + throw new Exception("No GLOBAL section"); + } + + foreach($this->cmpOpenSslConf["GLOBAL"] as $key => $val) { + $a[] = "\t" . $key . "=" . $val . ""; + } + + foreach($this->cmpOpenSslConf as $sec => $prm) { + if($sec == "GLOBAL") + continue; + + $a[] = ""; + $a[] = "[" . $sec . "]"; + + foreach($prm as $key => $val) { + $a[] = "\t" . $key . " = " . $val . ""; + } + } + + $a[] = ""; + + $t = join("\n", $a); + + + $rand = mt_rand(100000, 999999); + + $file = "/tmp/openssl-$rand.conf"; + + $w = @file_put_contents($file, $t); + + if(!$w) { + throw new Exception("Can't write file '$file'"); + } + + return $file; + } + + function cmpOpenSslConfRead($file) { + $t = file_get_contents($file); + + $a = explode("\n", $t); + + $sec = "GLOBAL"; + $key = ""; + $val = ""; + $obj = array(); + + for($i = 0; $i < count($a); $i++) { + $a[$i] = trim($a[$i], "\n \t\r"); + + if(!$a[$i]) + continue; + + if(substr($a[$i], 0, 1) == "#") + continue; + + $m = array(); + $s = ""; + + if(preg_match("/^(.+)#.+$/", $a[$i], $m)) { + $s = trim($m[1], "\n \t\r"); + } + else { + $s = $a[$i]; + } + + if(preg_match("/^\[(.+)\]$/", $a[$i], $m)) { + $sec = trim($m[1], "\n \t\r"); + + if(!isset($obj[$sec])) { + $obj[$sec] = array(); + } + + continue; + } + + $b = explode("=", $s, 2); + + $key = trim($b[0], "\n \t\r"); + $val = trim($b[1], "\n \t\r"); + + // echo "STR: " . $sec . " === " . $key . " === " . $val . "\n"; + + $obj[$sec][$key] = $val; + } + + $this->cmpOpenSslConf = $obj; + + // var_export($obj); + + return true; + } + + function cmpOpenSslParm($parm, $key, $def = "") { + if(!is_array($parm)) + return $def; + + if(!isset($parm[$key])) + return $def; + + return $parm[$key]; + } + + function cmpOpenSslParmConfSection($parm, $sec, &$out) { + if(!isset($this->cmpOpenSslConf[$sec])) { + ; + } + + foreach($this->cmpOpenSslConf[$sec] as $key => $val) { + $m = array(); + + if(!preg_match("/^(.+)_default$/", $key, $m)) + continue; + + $key = $m[1]; + + $out[$key] = $this->cmpOpenSslParm( + $parm, + $key, + $val + ); + } + + return true; + } + + function getCertInfo($crt, $prv, &$out = null) { + $txtPub = ""; + $txtPrv = ""; + + openssl_x509_export($crt , $txtPub, false ); + openssl_pkey_export($prv , $txtPrv, NULL ); + + if(!$out) + $out = array(); + + $out["fingerprint"] = array( + "default" => @openssl_x509_fingerprint($crt), + "sha256" => @openssl_x509_fingerprint($crt, "sha256") + ); + + $out["err"] = array(); + + do { + $cert = @openssl_x509_parse($txtPub); + + if(!$cert) { + $out["err"][] = array(__LINE__, openssl_error_string()); + break; + } + + if(!isset($cert["subject"])) { + $out["err"][] = array(__LINE__, "Invalid subject"); + break; + } + + if(!isset($cert["subject"]["CN"])) { + $out["err"][] = array(__LINE__, "Invalid subject CN"); + break; + } + + if(!isset($cert["extensions"])) { + $out["err"][] = array(__LINE__, "Invalid extensions"); + break; + } + + if(!isset($cert["extensions"]["authorityKeyIdentifier"])) { + $out["err"][] = array(__LINE__, "Invalid extensions authorityKeyIdentifier"); + break; + } + + if(!isset($cert["extensions"]["subjectKeyIdentifier"])) { + $out["err"][] = array(__LINE__, "Invalid extensions subjectKeyIdentifier"); + break; + } + } while(0); + + if($out["err"]) { + $this->d($out["err"]); + return NULL; + } + + unset($out["err"]); + + $nrmz = array( /* "A" => "a", "B" => "b", "C" => "c", "D" => "d", "E" => "e", "F" => "f", */ ":" => ""); + + do { + if(preg_match("/^[0-9A-F:]+$/", $cert["extensions"]["authorityKeyIdentifier"])) { + $certAuth = $cert["extensions"]["authorityKeyIdentifier"]; + break; + } + + $a = explode("\n", $cert["extensions"]["authorityKeyIdentifier"]); + $b = null; + $c = array(); + + for($i = 0; $i < count($a); $i++) { + $b = explode(":", $a[$i], 2); + $c[$b[0]] = $b[1]; + } + + // $this->d($c); + + if(!isset($c["keyid"]) || !$c["keyid"]) { + $out["err"][] = array(__LINE__, "Invalid authorityKeyIdentifier: '". $cert["extensions"]["authorityKeyIdentifier"] ."'"); + return NULL; + } + + $certAuth = strtolower($c["keyid"]); + } while(0); + + $certAuth = strtr($certAuth, $nrmz); + $certAuth = strtolower($certAuth); + + $certSubj = $cert["extensions"]["subjectKeyIdentifier"]; + $certSubj = strtr($certSubj, $nrmz); + $certSubj = strtolower($certSubj); + + $out["certAuth" ] = $certAuth; + $out["validFrom"] = date("Y-m-d H:i:s", $cert["validFrom_time_t" ]); + $out["validTo" ] = date("Y-m-d H:i:s", $cert["validTo_time_t" ]); + $out["certSubj" ] = $certSubj; + $out["certCN" ] = $cert["subject"]["CN"]; + $out["public" ] = $txtPub; + $out["private" ] = $txtPrv; + + return $out; + } + + function createCA($parm, &$out = null) { + try { + $confFile = $this->cmpOpenSslConfTemp(); + + $digest_alg = $this->cmpOpenSslParm($parm, "digest_alg" , "sha256" ); + $x509_extensions = $this->cmpOpenSslParm($parm, "x509_extensions" , "cmp_x509_ext_rsa" ); + $days = $this->cmpOpenSslParm($parm, "days" , 365 ); + $outfile = $this->cmpOpenSslParm($parm, "outfile" ); + $serial = $this->cmpOpenSslParm($parm, "serial" , mt_rand(0, PHP_INT_MAX) ); + + $this->caDN = array(); + + $this->cmpOpenSslParmConfSection($parm, "cmp_org", $this->caDN); + $this->cmpOpenSslParmConfSection($parm, "cmp_dst_ext", $this->caDN); + + if(!$this->caDN["commonName"]) { + throw new Exception("Empty commonName"); + } + + $confFile = $this->cmpOpenSslConfTemp(); + + $pcsrs = array( + "digest_alg" => $digest_alg , + ); + + $pcsrn = array( + "config" => $confFile , + "digest_alg" => $digest_alg , + "x509_extensions" => $x509_extensions , + ); + + $ppkey = array( + "config" => $confFile , + "encrypt_key" => $this->cmpOpenSslParm($parm, "encrypt_key" , false ), + "private_key_type" => $this->cmpOpenSslParm($parm, "private_key_type" , OPENSSL_KEYTYPE_RSA ), + "private_key_bits" => $this->cmpOpenSslParm($parm, "private_key_bits" , 4096 ), + ); + + $this->caPrv = openssl_pkey_new($ppkey); + + if(!$this->caPrv) { + throw new Exception("openssl_pkey_new: " . openssl_error_string()); + } + + $csr = openssl_csr_new($this->caDN, $this->caPrv, $pcsrn); + + if(!$csr) { + throw new Exception("openssl_csr_new: " . openssl_error_string()); + } + + // Создание самоподписанного сертификата со сроком жизни $days дней + $this->caCrt = openssl_csr_sign($csr, null, $this->caPrv, $days, $pcsrs, $serial); + + if(!$this->caCrt) { + throw new Exception("openssl_csr_sign: " . openssl_error_string()); + } + + @unlink($confFile); + } catch(Exception|Throwable $e) { + @unlink($confFile); + + $this->e($e); + + return NULL; + } + + $this->getCertInfo($this->caCrt, $this->caPrv, $out); + + $txtPub = ""; + $txtPrv = ""; + + openssl_x509_export($this->caCrt , $txtPub, false ); + openssl_pkey_export($this->caPrv , $txtPrv, NULL ); + + if($out !== null) { + if(!$this->getCertInfo($this->caCrt, $this->caPrv, $out)) + return NULL; + } + + if($outfile) { + openssl_x509_export_to_file($this->caCrt , "$outfile.crt" ); + openssl_pkey_export_to_file($this->caPrv , "$outfile.prv" , NULL ); + } + + $this->caPub = openssl_pkey_get_public($this->caCrt); + + if(!$this->caPub) { + $this->e(__LINE__, "openssl_pkey_get_public: error"); + return NULL; + } + + // var_export($csrout); + // echo "\n"; + + return true; + } + + function loadFromFileCACrt($file) { + // var_dump(openssl_get_cert_locations()); + + $this->caCrtFile = $file; + + $text = @file_get_contents($file); + + if($this->loadFromTextCACrt($text)) { + $this->caCrtFile = $file; + return true; + } + + return NULL; + } + + function loadFromTextCACrt($text) { + $this->caCrtFile = ""; + + $this->caCrtPEM = $text; + + if(!$this->caCrtPEM) { + $this->e(__LINE__, "Invalid CA text"); + return NULL; + } + + // openssl_get_privatekey() + $this->caCrt = openssl_x509_read( $this->caCrtPEM ); + + if(!$this->caCrt) { + $this->e(__LINE__, "openssl_x509_read: error"); + return NULL; + } + + // openssl_x509_parse(file_get_contents($file)); + + $this->caPub = openssl_pkey_get_public($this->caCrt); + + if(!$this->caPub) { + $this->e(__LINE__, "openssl_pkey_get_public: error"); + return NULL; + } + + $pkey = openssl_pkey_get_details($this->caPub); + + if(!$pkey) { + $this->e(__LINE__, "openssl_pkey_get_details: error"); + return NULL; + } + + $this->caPubPEM = $pkey["key"]; + + $this->caPub = openssl_pkey_get_public($this->caPubPEM); + + if(!$this->caPub) { + $this->e(__LINE__, "openssl_pkey_get_public: error"); + return NULL; + } + + return true; + } + + function loadFromFileCAPrv($file, $pass = NULL) { + $this->caPrvFile = $file; + + $text = @file_get_contents($file); + + if($this->loadFromTextCAPrv($text, $pass)) { + $this->caPrvFile = $file; + return true; + } + + return NULL; + } + + function loadFromTextCAPrv($text, $pass = NULL) { + $this->caPrvFile = ""; +/* + if(@$file) + $this->caPrvPEM = @file_get_contents($file); + else + $this->caPrvPEM = ""; + + if(!$text) { + $this->e(__LINE__, "Invalid CA private key text"); + return NULL; + } +*/ + $this->caPrvPEM = $text; + + $this->caPrv = openssl_pkey_get_private($this->caPrvPEM, $pass); + + if(!$this->caPrv) { + $this->e(__LINE__, "openssl_pkey_get_private: error"); + return NULL; + } + + $sign = ""; + $test = "test-test"; + + //Вычисляем подпись + if(!openssl_sign($test, $sign, $this->caPrv, "sha1WithRSAEncryption")) { + $this->e(__LINE__, "openssl_sign: error"); + return NULL; + } + + switch( openssl_verify($test, $sign, $this->caPub, OPENSSL_ALGO_SHA1) ) { + case 1: + // echo "корректна\n"; + return true; + + case 0: + // echo "некорректна\n"; + $this->e(__LINE__, "Incorrect CA private key"); + return NULL; + + case -1: + $this->e(__LINE__, openssl_error_string()); + return NULL; + } + + return true; + } + + + function infoCA() { + var_export(openssl_x509_parse($this->caCrt)); + echo "\n"; + + // var_export(openssl_pkey_get_details($this->caPrv)); + // echo "\n"; + } + + + function createCli($parm, &$out = null) { + try { + $confFile = $this->cmpOpenSslConfTemp(); + + $digest_alg = $this->cmpOpenSslParm($parm, "digest_alg" , "sha256" ); + $x509_extensions = $this->cmpOpenSslParm($parm, "x509_extensions" , "" ); + $days = $this->cmpOpenSslParm($parm, "days" , 365 ); + $outfile = $this->cmpOpenSslParm($parm, "outfile" ); + $serial = $this->cmpOpenSslParm($parm, "serial" , mt_rand(0, PHP_INT_MAX) ); + + $this->cliDN = array(); + + $this->cmpOpenSslParmConfSection($parm, "cmp_org", $this->cliDN); + $this->cmpOpenSslParmConfSection($parm, "cmp_dst_ext", $this->cliDN); + + if(!$this->cliDN["commonName"]) { + throw new Exception("Empty commonName"); + } + + if(!$x509_extensions) { + throw new Exception("Empty x509_extensions"); + } + + $pcsrn = array( + "config" => $confFile , + "digest_alg" => $digest_alg , + "x509_extensions" => $x509_extensions , + ); + + $ppkey = array( + "config" => $confFile , + "encrypt_key" => $this->cmpOpenSslParm($parm, "encrypt_key" , false ), + "private_key_type" => $this->cmpOpenSslParm($parm, "private_key_type" , OPENSSL_KEYTYPE_RSA ), + "private_key_bits" => $this->cmpOpenSslParm($parm, "private_key_bits" , 4096 ), + ); + + $this->cliPrv = openssl_pkey_new($ppkey); + + if(!$this->cliPrv) { + throw new Exception("openssl_csr_new: " . openssl_error_string()); + } + + $csr = @openssl_csr_new($this->cliDN, $this->cliPrv, $pcsrn); + + if(!$csr) { + throw new Exception("openssl_csr_new: " . openssl_error_string()); + } + + $this->cliCrt = openssl_csr_sign($csr, $this->caCrt, $this->caPrv, $days, $pcsrn, $serial); + + if(!$this->cliCrt) { + throw new Exception("openssl_csr_sign: " . openssl_error_string()); + } + + @unlink($confFile); + } catch(Exception|Throwable $e) { + @unlink($confFile); + + $this->e($e); + + return NULL; + } + + $txtPub = ""; + $txtPrv = ""; + + openssl_x509_export($this->cliCrt, $txtPub, false ); + openssl_pkey_export($this->cliPrv, $txtPrv, NULL ); + + if($out !== null) { + if(!$this->getCertInfo($this->cliCrt, $this->cliPrv, $out)) + return NULL; + } + + if($outfile) { + openssl_x509_export_to_file($this->cliCrt , "$outfile.crt" ); + openssl_pkey_export_to_file($this->cliPrv , "$outfile.prv" , NULL ); + } + + $this->cliPub = openssl_pkey_get_public($this->cliCrt); + + if(!$this->cliPub) { + $this->e(__LINE__, "openssl_pkey_get_public: error"); + return NULL; + } + + // var_export($csrout); + // echo "\n"; + + return true; + } + + function createClient($parm = NULL, &$out = null) { + $parm["x509_extensions"] = "cmp_x509_ext_cli"; + return $this->createCli($parm, $out); + } + + function createServer($parm = NULL, &$out = null) { + $parm["x509_extensions"] = "cmp_x509_ext_srv"; + return $this->createCli($parm, $out); + } + + function cmpOpenSslGenDh($bits = 2048) { + $a = array( + "openssl", + "dhparam", + $bits + ); + + if(!method_exists($this, "cmpSysExec")) { + $this->d("Invalid method cmpSysExec"); + return null; + } + + $arr = $this->cmpSysExec($a, array("return" => "outarr", "noerror" => 1)); + + if(0) { + var_export($arr); + echo "\n"; + } + + if($arr[0] != "-----BEGIN DH PARAMETERS-----") { + $this->d("Invalid first string"); + return null; + } + + $lst = count($arr) - 2; + + if($arr[$lst] != "-----END DH PARAMETERS-----") { + $this->d("Invalid last string"); + return null; + } + + return join("\n", $arr); + } + + function cmpOpenVpnGenTa() { + $a = array( + "openvpn", + "--genkey", + // Valid keytype arguments are: + "secret" // Standard OpenVPN shared secret keys + // "tls-crypt" // Alias for secret + // "tls-auth" // Alias for secret + ); + + $arr = $this->cmpSysExec($a, array("return" => "outarr", "noerror" => 1)); + + if(0) { + var_export($arr); + echo "\n"; + } + + $idx = array(); + + for($i = 0; $i < count($arr); $i++) { + if($arr[$i] == "-----BEGIN OpenVPN Static key V1-----") { + $idx["bgn"] = $i; + continue; + } + + if($arr[$i] == "-----END OpenVPN Static key V1-----") { + $idx["end"] = $i; + continue; + } + } + + if(!isset($idx["bgn"]) || !isset($idx["end"])) { + $this->d("Invalid output key"); + return null; + } + + return join("\n", $arr); + } + + function cmpOpenSslGenCrl($caCrtText, $caPrvText, $outCrlFile) { + $now = date("Y-m-d H:i:s"); + $dir = "/tmp/tmp-ca-dir-" . md5("tmp-ca-dir-" . $now); + + if(!mkdir($dir)) + return null; + + $caCrtFile = $dir . "/ca.crt"; + $caPrvFile = $dir . "/ca.prv"; + $indexFile = $dir . "/index.txt"; + $serialFile = $dir . "/serial"; + + file_put_contents($caCrtFile, $caCrtText); + file_put_contents($caPrvFile, $caPrvText); + + file_put_contents($indexFile, ""); + file_put_contents($serialFile, ""); + + $a = array( + "cd" , + $dir , + ["asis", "&&"] , + "openssl" , + "ca" , + "-config" , + "65-openssl.cnf" , + "-gencrl" , + "-out" , + $outCrlFile , + "-cert" , + $caCrtFile , + "-keyfile" , + $caPrvFile , + ); + + $arr = $this->cmpSysExec($a, array(/* "return" => "outarr", "noerror" => 1 */)); + + unlink($caCrtFile); + unlink($caPrvFile); + unlink($indexFile); + unlink($serialFile); + + if(!rmdir($dir)) { + $this->d("Can't remove directory '$dir'"); + } + + if(1) { + var_export($arr); + echo "\n"; + } + + return; + } + + function cmpOpenSslAddCrl($caCrtText, $caPrvText, $outCrlFile, $sjCrtText) { + $now = date("Y-m-d H:i:s"); + $dir = "/tmp/tmp-ca-dir-" . md5("tmp-ca-dir-" /* . $now . "-" . mt_rand(10000, 99999) */ ); + + if(!mkdir($dir)) { + ; + // return null; + } + + $caCrtFile = $dir . "/ca.crt"; + $caPrvFile = $dir . "/ca.prv"; + $indexFile = $dir . "/index.txt"; + $serialFile= $dir . "/serial"; + $sjCrtFile = $dir . "/cert.pem"; + + $crlFile = $dir . "/crl.pem"; + + if(!is_file($caCrtFile)) + file_put_contents($caCrtFile, $caCrtText); + if(!is_file($caPrvFile)) + file_put_contents($caPrvFile, $caPrvText); + + file_put_contents($sjCrtFile, $sjCrtText); + + if(!is_file($indexFile)) + file_put_contents($indexFile, ""); + if(!is_file($serialFile)) + file_put_contents($serialFile, ""); + + if(is_file($outCrlFile)) { + copy($outCrlFile, $crlFile); + // $a[] = "-in"; + // $a[] = $outCrlFile; + $this->d("Add IN"); + } + + $a = array( + "cd" , + $dir , + ["asis", "&&"] , + "openssl" , + "ca" , + "-config" , + "65-openssl.cnf" , + "-revoke" , + $sjCrtFile , + // "-out" , + // $outCrlFile , + "-cert" , + $caCrtFile , + "-keyfile" , + $caPrvFile , + ); + + // $a[] = "-in"; + // $a[] = $outCrlFile; + + $arr = $this->cmpSysExec($a, array(/* "return" => "outarr", "noerror" => 1 */)); + + if(1) { + var_export($arr); + echo "\n"; + } + + // unlink($caCrtFile); + // unlink($caPrvFile); + // unlink($sjCrtFile); + // unlink($indexFile); + // unlink($serialFile); + + if(is_file($crlFile)) { + copy($crlFile, $outCrlFile); + // unlink($crlFile); + } + + // unlink($dir . "/index.txt.attr"); + // unlink($dir . "/index.txt.old"); + + // if(!rmdir($dir)) { + // $this->d("Can't remove directory '$dir'"); + // } + + return; + } + + // trait + }