コード例 #1
0
ファイル: Setup.php プロジェクト: kelunik/acme-client
 public function doExecute(Manager $args)
 {
     $email = $args->get("email");
     (yield \Amp\resolve($this->checkEmail($email)));
     $server = \Kelunik\AcmeClient\resolveServer($args->get("server"));
     $keyFile = \Kelunik\AcmeClient\serverToKeyname($server);
     $path = "accounts/{$keyFile}.pem";
     $bits = 4096;
     $keyStore = new KeyStore(\Kelunik\AcmeClient\normalizePath($args->get("storage")));
     $this->climate->br();
     try {
         $keyPair = (yield $keyStore->get($path));
         $this->climate->whisper("    Using existing private key ...");
     } catch (KeyStoreException $e) {
         $this->climate->whisper("    No private key found, generating new one ...");
         $keyPair = (new OpenSSLKeyGenerator())->generate($bits);
         $keyPair = (yield $keyStore->put($path, $keyPair));
         $this->climate->whisper("    Generated new private key with {$bits} bits.");
     }
     $acme = $this->acmeFactory->build($server, $keyPair);
     $this->climate->whisper("    Registering with " . substr($server, 8) . " ...");
     /** @var Registration $registration */
     $registration = (yield $acme->register($email));
     $this->climate->info("    Registration successful. Contacts: " . implode(", ", $registration->getContact()));
     $this->climate->br();
     (yield new CoroutineResult(0));
 }
コード例 #2
0
ファイル: KeyStore.php プロジェクト: kelunik/acme-client
 public function put($path, KeyPair $keyPair)
 {
     if (!is_string($path)) {
         throw new InvalidArgumentException(sprintf("\$root must be of type string, %s given.", gettype($path)));
     }
     return \Amp\resolve($this->doPut($path, $keyPair));
 }
コード例 #3
0
ファイル: Issue.php プロジェクト: sam002/yii2-acme
 /**
  * @param $domains
  * @return \Generator
  * @throws AcmeException
  */
 private function doIssue($domains)
 {
     //validate domains
     (yield \Amp\resolve($this->checkDnsRecords($domains)));
     //todo check avalibles aliases an applications and find each roots
     $keyFile = $this->serverToKeyName();
     try {
         $keyPair = $this->getKeyStorage()->get($keyFile);
     } catch (FilesystemException $e) {
         throw new InvalidCallException("Account key not found, did you run 'yii acme/setup' or 'yii acme/quick'?", 0, $e);
     }
     $acme = $this->getAcmeService($keyPair);
     $promises = [];
     foreach ($domains as $domain) {
         $promises[] = \Amp\resolve($this->solveChallenge($acme, $keyPair, $domain));
     }
     list($errors) = (yield \Amp\any($promises));
     if (!empty($errors)) {
         foreach ($errors as $error) {
             echo $error->getMessage() . PHP_EOL;
         }
         throw new AcmeException("Issuance failed, not all challenges could be solved.");
     }
     $path = implode(DIRECTORY_SEPARATOR, ['certs', $this->serverToKeyName(), reset($domains)]);
     $keyPath = $path . DIRECTORY_SEPARATOR . 'key';
     try {
         $keyPair = $this->getKeyStorage()->get($keyPath);
     } catch (FilesystemException $e) {
         $keyPair = (new OpenSSLKeyGenerator())->generate($this->keyLength);
         $keyPair = $this->getKeyStorage()->put($keyPath, $keyPair);
     }
     $location = (yield $acme->requestCertificate($keyPair, $domains));
     $certificates = (yield $acme->pollForCertificate($location));
     $certificateStore = $this->getCertificateStorage();
     $certificateStore->setRoot($certificateStore->getRoot() . $path);
     $result = $certificateStore->put($certificates);
     (yield new CoroutineResult($result));
 }
コード例 #4
0
ファイル: Dns01.php プロジェクト: kelunik/acme
 /**
  * Verifies a DNS-01 Challenge.
  *
  * Can be used to verify a challenge before requesting validation from a CA to catch errors early.
  *
  * @api
  * @param string $domain domain to verify
  * @param string $keyAuthorization key authorization (expected payload)
  * @return \Amp\Promise resolves to the DNS entry found
  * @throws AcmeException If the challenge could not be verified.
  */
 public function verifyChallenge($domain, $keyAuthorization)
 {
     return \Amp\resolve($this->doVerifyChallenge($domain, $keyAuthorization));
 }
コード例 #5
0
 public function delete($name)
 {
     return \Amp\resolve($this->doDelete($name));
 }
コード例 #6
0
ファイル: UvDriver.php プロジェクト: staabm/file
 /**
  * {@inheritdoc}
  */
 public function put($path, $contents)
 {
     return \Amp\resolve($this->doPut($path, $contents), $this->reactor);
 }
コード例 #7
0
ファイル: functions.php プロジェクト: ridwanbejo/petabencana
function __init()
{
    $state = new \StdClass();
    $state->messageFactory = new MessageFactory();
    $state->questionFactory = new QuestionFactory();
    $state->encoder = (new EncoderFactory())->create();
    $state->decoder = (new DecoderFactory())->create();
    $state->arrayCache = new ArrayCache();
    $state->requestIdCounter = 1;
    $state->pendingRequests = [];
    $state->serverIdMap = [];
    $state->serverUriMap = [];
    $state->serverIdTimeoutMap = [];
    $state->now = \time();
    $state->serverTimeoutWatcher = \Amp\repeat(function ($watcherId) use($state) {
        $state->now = $now = \time();
        foreach ($state->serverIdTimeoutMap as $id => $expiry) {
            if ($now > $expiry) {
                __unloadServer($state, $id);
            }
        }
        if (empty($state->serverIdMap)) {
            \Amp\disable($watcherId);
        }
    }, 1000, $options = ["enable" => true, "keep_alive" => false]);
    $state->config = (yield \Amp\resolve(__loadResolvConf()));
    (yield new CoroutineResult($state));
}
コード例 #8
0
ファイル: Revoke.php プロジェクト: sam002/yii2-acme
 /**
  * @param string $name
  * @return mixed
  * @throws \Throwable
  */
 public function revoke($name = '')
 {
     return \Amp\wait(\Amp\resolve($this->doRevoke($name)));
 }
コード例 #9
0
ファイル: Http01.php プロジェクト: kelunik/acme
 /**
  * Verifies a HTTP-01 challenge.
  *
  * Can be used to verify a challenge before requesting validation from a CA to catch errors early.
  *
  * @api
  * @param string $domain domain to verify
  * @param string $token challenge token
  * @param string $payload expected payload
  * @return \Amp\Promise resolves to null
  * @throws AcmeException If the challenge could not be verified.
  */
 public function verifyChallenge($domain, $token, $payload)
 {
     return \Amp\resolve($this->doVerifyChallenge($domain, $token, $payload));
 }
コード例 #10
0
ファイル: DefaultResolver.php プロジェクト: amphp/dns
 private function doResolve($name, array $types, $options)
 {
     if (!$this->config) {
         $this->config = (yield \Amp\resolve($this->loadResolvConf()));
     }
     if (empty($types)) {
         (yield new CoroutineResult([]));
         return;
     }
     assert(array_reduce($types, function ($result, $val) {
         return $result && \is_int($val);
     }, true), 'The $types passed to DNS functions must all be integers (from \\Amp\\Dns\\Record class)');
     $name = \strtolower($name);
     $result = [];
     // Check for cache hits
     if (!isset($options["cache"]) || $options["cache"]) {
         foreach ($types as $k => $type) {
             $cacheKey = "{$name}#{$type}";
             $cacheValue = (yield $this->arrayCache->get($cacheKey));
             if ($cacheValue !== null) {
                 $result[$type] = $cacheValue;
                 unset($types[$k]);
             }
         }
         if (empty($types)) {
             if (empty(array_filter($result))) {
                 throw new NoRecordException("No records returned for {$name} (cached result)");
             } else {
                 (yield new CoroutineResult($result));
                 return;
             }
         }
     }
     $timeout = empty($options["timeout"]) ? $this->config["timeout"] : (int) $options["timeout"];
     if (empty($options["server"])) {
         if (empty($this->config["nameservers"])) {
             throw new ResolutionException("No nameserver specified in system config");
         }
         $uri = "udp://" . $this->config["nameservers"][0];
     } else {
         $uri = $this->parseCustomServerUri($options["server"]);
     }
     foreach ($types as $type) {
         $promises[] = $this->doRequest($uri, $name, $type);
     }
     try {
         list(, $resultArr) = (yield \Amp\timeout(\Amp\some($promises), $timeout));
         foreach ($resultArr as $value) {
             $result += $value;
         }
     } catch (\Amp\TimeoutException $e) {
         if (substr($uri, 0, 6) == "tcp://") {
             throw new TimeoutException("Name resolution timed out for {$name}");
         } else {
             $options["server"] = \preg_replace("#[a-z.]+://#", "tcp://", $uri);
             (yield new CoroutineResult(\Amp\resolve($this->doResolve($name, $types, $options))));
             return;
         }
     } catch (ResolutionException $e) {
         if (empty($result)) {
             // if we have no cached results
             throw $e;
         }
     } catch (CombinatorException $e) {
         // if all promises in Amp\some fail
         if (empty($result)) {
             // if we have no cached results
             foreach ($e->getExceptions() as $ex) {
                 if ($ex instanceof NoRecordException) {
                     throw new NoRecordException("No records returned for {$name}", 0, $e);
                 }
             }
             throw new ResolutionException("All name resolution requests failed", 0, $e);
         }
     }
     (yield new CoroutineResult($result));
 }
コード例 #11
0
ファイル: AcmeClient.php プロジェクト: DSpeichert/acme
 public function post($resource, array $payload)
 {
     if (!is_string($resource)) {
         throw new InvalidArgumentException(sprintf("\$resource must be of type string, %s given.", gettype($resource)));
     }
     return \Amp\resolve($this->doPost($resource, $payload));
 }
コード例 #12
0
ファイル: Check.php プロジェクト: kelunik/acme-client
 public function execute(Manager $args)
 {
     return \Amp\resolve($this->doExecute($args));
 }
コード例 #13
0
ファイル: AcmeService.php プロジェクト: DSpeichert/acme
 public function revokeCertificate($pem)
 {
     if (!is_string($pem)) {
         throw new InvalidArgumentException(sprintf("\$pem must be of type string, %s given.", gettype($pem)));
     }
     return \Amp\resolve($this->doRevokeCertificate($pem));
 }
コード例 #14
0
ファイル: AcmeService.php プロジェクト: kelunik/acme
 /**
  * Revokes a certificate.
  *
  * @api
  * @param string $pem PEM encoded certificate
  * @return \Amp\Promise resolves to true
  * @throws AcmeException If something went wrong.
  */
 public function revokeCertificate($pem)
 {
     return \Amp\resolve($this->doRevokeCertificate($pem));
 }
コード例 #15
0
ファイル: Issue.php プロジェクト: kelunik/acme-client
 private function doExecute(Manager $args)
 {
     if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
         if (posix_geteuid() !== 0) {
             $processUser = posix_getpwnam(posix_geteuid());
             $currentUsername = $processUser["name"];
             $user = $args->get("user") ?: $currentUsername;
             if ($currentUsername !== $user) {
                 throw new AcmeException("Running this script with --user only works as root!");
             }
         } else {
             $user = $args->get("user") ?: "www-data";
         }
     }
     $domains = array_map("trim", explode(":", str_replace([",", ";"], ":", $args->get("domains"))));
     (yield \Amp\resolve($this->checkDnsRecords($domains)));
     $docRoots = explode(PATH_SEPARATOR, str_replace("\\", "/", $args->get("path")));
     $docRoots = array_map(function ($root) {
         return rtrim($root, "/");
     }, $docRoots);
     if (count($domains) < count($docRoots)) {
         throw new AcmeException("Specified more document roots than domains.");
     }
     if (count($domains) > count($docRoots)) {
         $docRoots = array_merge($docRoots, array_fill(count($docRoots), count($domains) - count($docRoots), end($docRoots)));
     }
     $keyStore = new KeyStore(\Kelunik\AcmeClient\normalizePath($args->get("storage")));
     $server = \Kelunik\AcmeClient\resolveServer($args->get("server"));
     $keyFile = \Kelunik\AcmeClient\serverToKeyname($server);
     try {
         $keyPair = (yield $keyStore->get("accounts/{$keyFile}.pem"));
     } catch (KeyStoreException $e) {
         throw new AcmeException("Account key not found, did you run 'bin/acme setup'?", 0, $e);
     }
     $this->climate->br();
     $acme = $this->acmeFactory->build($server, $keyPair);
     $errors = [];
     $domainChunks = array_chunk($domains, 10, true);
     foreach ($domainChunks as $domainChunk) {
         $promises = [];
         foreach ($domainChunk as $i => $domain) {
             $promises[] = \Amp\resolve($this->solveChallenge($acme, $keyPair, $domain, $docRoots[$i]));
         }
         list($chunkErrors) = (yield \Amp\any($promises));
         $errors += $chunkErrors;
     }
     if (!empty($errors)) {
         foreach ($errors as $error) {
             $this->climate->error($error->getMessage());
         }
         throw new AcmeException("Issuance failed, not all challenges could be solved.");
     }
     $path = "certs/" . $keyFile . "/" . reset($domains) . "/key.pem";
     $bits = $args->get("bits");
     try {
         $keyPair = (yield $keyStore->get($path));
     } catch (KeyStoreException $e) {
         $keyPair = (new OpenSSLKeyGenerator())->generate($bits);
         $keyPair = (yield $keyStore->put($path, $keyPair));
     }
     $this->climate->br();
     $this->climate->whisper("    Requesting certificate ...");
     $location = (yield $acme->requestCertificate($keyPair, $domains));
     $certificates = (yield $acme->pollForCertificate($location));
     $path = \Kelunik\AcmeClient\normalizePath($args->get("storage")) . "/certs/" . $keyFile;
     $certificateStore = new CertificateStore($path);
     (yield $certificateStore->put($certificates));
     $this->climate->info("    Successfully issued certificate.");
     $this->climate->info("    See {$path}/" . reset($domains));
     $this->climate->br();
     (yield new CoroutineResult(0));
 }
コード例 #16
0
ファイル: AcmeClient.php プロジェクト: kelunik/acme
 /**
  * Retrieves a resource using a POST request.
  *
  * @api
  * @param string $resource resource to fetch
  * @param array  $payload
  * @return \Amp\Promise resolves to the HTTP response
  * @throws AcmeException If the request failed.
  */
 public function post($resource, array $payload)
 {
     return \Amp\resolve($this->doPost($resource, $payload));
 }
コード例 #17
0
ファイル: 004_multi_rows.php プロジェクト: amphp/mysql
<?php

require './example_bootstrap.php';
require 'support/generic_table.php';
\Amp\run(function () {
    $db = new \Amp\Mysql\Pool("host=" . DB_HOST . ";user="******";pass="******";db=" . DB_NAME);
    /* create same table than in 003_generic_with_yield.php */
    (yield \Amp\resolve(genTable($db)));
    /* yeah, we need a lot of yields and assigns here... With PHP 7 we finally can drop a lot of stupid parenthesis! */
    $query = (yield $db->query("SELECT a * b FROM tmp"));
    while ((list($result) = (yield $query->fetchRow())) !== null) {
        var_dump($result);
        // outputs each row of the resultset returned by SELECT a * b FROM tmp
    }
    /* or, maybe, wait until they're all fetched (because you anyway only can continue after having full resultset */
    $query = (yield $db->query("SELECT a * b FROM tmp"));
    $objs = (yield $query->fetchObjects());
    var_dump($objs);
    // outputs all the rows as objects of the resultset returned by SELECT a * b FROM tmp
    (yield $db->query("DROP TABLE tmp"));
    $db->close();
});
コード例 #18
0
 public function delete($token)
 {
     return \Amp\resolve($this->doDelete($token));
 }
コード例 #19
0
ファイル: Dns01.php プロジェクト: kelunik/acme
 /**
  * Verifies a DNS-01 Challenge.
  *
  * Can be used to verify a challenge before requesting validation from a CA to catch errors early.
  *
  * @api
  * @param string $domain domain to verify
  * @param string $expectedPayload expected DNS record value
  * @return \Amp\Promise resolves to the DNS entry found
  * @throws AcmeException If the challenge could not be verified.
  */
 public function verifyChallenge($domain, $expectedPayload)
 {
     return \Amp\resolve($this->doVerifyChallenge($domain, $expectedPayload));
 }
コード例 #20
0
ファイル: WatcherProcess.php プロジェクト: beentrill/aerys
 private function commandParser($client) : \Generator
 {
     $readWatcherId = yield;
     $buffer = "";
     $length = null;
     do {
         yield;
         $data = @fread($client, 8192);
         if ($data == "" && (!is_resource($client) || @feof($client))) {
             \Amp\cancel($readWatcherId);
             return;
         }
         $buffer .= $data;
         do {
             if (!isset($length)) {
                 if (!isset($buffer[3])) {
                     break;
                 }
                 $length = unpack("Nlength", substr($buffer, 0, 4))["length"];
                 $buffer = substr($buffer, 4);
             }
             if (!isset($buffer[$length - 1])) {
                 break;
             }
             $message = @\json_decode(substr($buffer, 0, $length), true);
             $buffer = (string) substr($buffer, $length);
             $length = null;
             if (!isset($message["action"])) {
                 continue;
             }
             switch ($message["action"]) {
                 case "restart":
                     $this->restart();
                     break;
                 case "stop":
                     \Amp\resolve($this->stop())->when('Amp\\stop');
                     break;
             }
         } while (1);
     } while (1);
 }
コード例 #21
0
ファイル: Setup.php プロジェクト: sam002/yii2-acme
 /**
  * @param $email
  * @return Registration
  * @throws \Throwable
  */
 public function setup($email)
 {
     return \Amp\wait(\Amp\resolve($this->doSetup($email)));
 }
コード例 #22
0
ファイル: Auto.php プロジェクト: kelunik/acme-client
 /**
  * @param Manager $args
  * @return \Generator
  */
 private function doExecute(Manager $args)
 {
     $configPath = $args->get("config");
     try {
         $config = Yaml::parse((yield \Amp\File\get($configPath)));
     } catch (FilesystemException $e) {
         $this->climate->error("Config file ({$configPath}) not found.");
         (yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
         return;
     } catch (ParseException $e) {
         $this->climate->error("Config file ({$configPath}) had an invalid format and couldn't be parsed.");
         (yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
         return;
     }
     if ($args->defined("server")) {
         $config["server"] = $args->get("server");
     } else {
         if (!isset($config["server"]) && $args->exists("server")) {
             $config["server"] = $args->get("server");
         }
     }
     if ($args->defined("storage")) {
         $config["storage"] = $args->get("storage");
     } else {
         if (!isset($config["storage"]) && $args->exists("storage")) {
             $config["storage"] = $args->get("storage");
         }
     }
     if (!isset($config["server"])) {
         $this->climate->error("Config file ({$configPath}) didn't have a 'server' set nor was it passed as command line argument.");
         (yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
         return;
     }
     if (!isset($config["storage"])) {
         $this->climate->error("Config file ({$configPath}) didn't have a 'storage' set nor was it passed as command line argument.");
         (yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
         return;
     }
     if (!isset($config["email"])) {
         $this->climate->error("Config file ({$configPath}) didn't have a 'email' set.");
         (yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
         return;
     }
     if (!isset($config["certificates"]) || !is_array($config["certificates"])) {
         $this->climate->error("Config file ({$configPath}) didn't have a 'certificates' section that's an array.");
         (yield new CoroutineResult(self::EXIT_CONFIG_ERROR));
         return;
     }
     $command = implode(" ", array_map("escapeshellarg", [PHP_BINARY, $GLOBALS["argv"][0], "setup", "--server", $config["server"], "--storage", $config["storage"], "--email", $config["email"]]));
     $process = new Process($command);
     $result = (yield $process->exec(Process::BUFFER_ALL));
     if ($result->exit !== 0) {
         $this->climate->error("Registration failed ({$result->exit})");
         $this->climate->error($command);
         $this->climate->br()->out($result->stdout);
         $this->climate->br()->error($result->stderr);
         (yield new CoroutineResult(self::EXIT_SETUP_ERROR));
         return;
     }
     $certificateChunks = array_chunk($config["certificates"], 10, true);
     $errors = [];
     $values = [];
     foreach ($certificateChunks as $certificateChunk) {
         $promises = [];
         foreach ($certificateChunk as $certificate) {
             $promises[] = \Amp\resolve($this->checkAndIssue($certificate, $config["server"], $config["storage"]));
         }
         list($chunkErrors, $chunkValues) = (yield \Amp\any($promises));
         $errors += $chunkErrors;
         $values += $chunkValues;
     }
     $status = ["no_change" => count(array_filter($values, function ($value) {
         return $value === self::STATUS_NO_CHANGE;
     })), "renewed" => count(array_filter($values, function ($value) {
         return $value === self::STATUS_RENEWED;
     })), "failure" => count($errors)];
     if ($status["renewed"] > 0) {
         foreach ($values as $i => $value) {
             if ($value === self::STATUS_RENEWED) {
                 $certificate = $config["certificates"][$i];
                 $this->climate->info("Certificate for " . implode(", ", array_keys($this->toDomainPathMap($certificate["paths"]))) . " successfully renewed.");
             }
         }
     }
     if ($status["failure"] > 0) {
         foreach ($errors as $i => $error) {
             $certificate = $config["certificates"][$i];
             $this->climate->error("Issuance for the following domains failed: " . implode(", ", array_keys($this->toDomainPathMap($certificate["paths"]))));
             $this->climate->error("Reason: {$error}");
         }
         $exitCode = $status["renewed"] > 0 ? self::EXIT_ISSUANCE_PARTIAL : self::EXIT_ISSUANCE_ERROR;
         (yield new CoroutineResult($exitCode));
         return;
     }
     if ($status["renewed"] > 0) {
         (yield new CoroutineResult(self::EXIT_ISSUANCE_OK));
         return;
     }
 }
コード例 #23
0
ファイル: functions.php プロジェクト: ridwanbejo/petabencana
/**
 * Enable encryption on an existing socket stream
 *
 * @param resource $socket
 * @param array $options
 * @return \Amp\Promise
 */
function cryptoEnable($socket, array $options = [])
{
    $isLegacy = PHP_VERSION_ID < 50600;
    if ($isLegacy) {
        // For pre-5.6 we always manually verify names in userland
        // using the captured peer certificate.
        $options["capture_peer_cert"] = true;
        $options["verify_peer"] = isset($options["verify_peer"]) ? $options["verify_peer"] : true;
        if (isset($options["CN_match"])) {
            $peerName = $options["CN_match"];
            $options["peer_name"] = $peerName;
            unset($options["CN_match"]);
        }
        if (empty($options["cafile"])) {
            $options["cafile"] = __DIR__ . "/../var/ca-bundle.crt";
        }
    }
    $options["SNI_nb_hack"] = false;
    if (empty($options["ciphers"])) {
        $options["ciphers"] = \implode(':', ["ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES256-GCM-SHA384", "ECDHE-ECDSA-AES256-GCM-SHA384", "DHE-RSA-AES128-GCM-SHA256", "DHE-DSS-AES128-GCM-SHA256", "kEDH+AESGCM", "ECDHE-RSA-AES128-SHA256", "ECDHE-ECDSA-AES128-SHA256", "ECDHE-RSA-AES128-SHA", "ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-SHA384", "ECDHE-ECDSA-AES256-SHA384", "ECDHE-RSA-AES256-SHA", "ECDHE-ECDSA-AES256-SHA", "DHE-RSA-AES128-SHA256", "DHE-RSA-AES128-SHA", "DHE-DSS-AES128-SHA256", "DHE-RSA-AES256-SHA256", "DHE-DSS-AES256-SHA", "DHE-RSA-AES256-SHA", "AES128-GCM-SHA256", "AES256-GCM-SHA384", "ECDHE-RSA-RC4-SHA", "ECDHE-ECDSA-RC4-SHA", "AES128", "AES256", "RC4-SHA", "HIGH", "!aNULL", "!eNULL", "!EXPORT", "!DES", "!3DES", "!MD5", "!PSK"]);
    }
    if (isset($options["crypto_method"])) {
        $method = $options["crypto_method"];
        unset($options["crypto_method"]);
    } elseif (PHP_VERSION_ID >= 50600 && PHP_VERSION_ID < 50606) {
        $method = \STREAM_CRYPTO_METHOD_TLS_CLIENT;
    } else {
        $method = \STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
    }
    \stream_context_set_option($socket, ["ssl" => $options]);
    $enable = true;
    return $isLegacy ? \Amp\resolve(__watchCryptoLegacy($enable, $method, $socket)) : __watchCrypto($enable, $method, $socket);
}
コード例 #24
0
ファイル: functions.php プロジェクト: amphp/socket
/**
 * Enable encryption on an existing socket stream
 *
 * @param resource $socket
 * @param array $options
 * @return \Amp\Promise
 */
function cryptoEnable($socket, array $options = [])
{
    static $caBundleFiles = [];
    $isLegacy = PHP_VERSION_ID < 50600;
    if ($isLegacy) {
        // For pre-5.6 we always manually verify names in userland
        // using the captured peer certificate.
        $options["capture_peer_cert"] = true;
        $options["verify_peer"] = isset($options["verify_peer"]) ? $options["verify_peer"] : true;
        if (isset($options["CN_match"])) {
            $peerName = $options["CN_match"];
            $options["peer_name"] = $peerName;
            unset($options["CN_match"]);
        }
        if (empty($options["cafile"])) {
            $options["cafile"] = __DIR__ . "/../var/ca-bundle.crt";
        }
    }
    // Externalize any bundle inside a Phar, because OpenSSL doesn't support the stream wrapper.
    if (!empty($options["cafile"]) && strpos($options["cafile"], "phar://") === 0) {
        // Yes, this is blocking but way better than just an error.
        if (!isset($caBundleFiles[$options["cafile"]])) {
            $bundleContent = file_get_contents($options["cafile"]);
            $caBundleFile = tempnam(sys_get_temp_dir(), "openssl-ca-bundle-");
            file_put_contents($caBundleFile, $bundleContent);
            register_shutdown_function(function () use($caBundleFile) {
                @unlink($caBundleFile);
            });
            $caBundleFiles[$options["cafile"]] = $caBundleFile;
        }
        $options["cafile"] = $caBundleFiles[$options["cafile"]];
    }
    if (empty($options["ciphers"])) {
        // See https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29
        // DES ciphers have been explicitly removed from that list
        // TODO: We're using the recommended settings for servers here, we need a good resource for clients.
        // Then we might be able to use a more restrictive list.
        // The following cipher suites have been explicitly disabled, taken from previous configuration:
        // !aNULL:!eNULL:!EXPORT:!DES:!DSS:!3DES:!MD5:!PSK
        $options["ciphers"] = \implode(':', ["ECDHE-ECDSA-CHACHA20-POLY1305", "ECDHE-RSA-CHACHA20-POLY1305", "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES256-GCM-SHA384", "ECDHE-RSA-AES256-GCM-SHA384", "DHE-RSA-AES128-GCM-SHA256", "DHE-RSA-AES256-GCM-SHA384", "ECDHE-ECDSA-AES128-SHA256", "ECDHE-RSA-AES128-SHA256", "ECDHE-ECDSA-AES128-SHA", "ECDHE-RSA-AES256-SHA384", "ECDHE-RSA-AES128-SHA", "ECDHE-ECDSA-AES256-SHA384", "ECDHE-ECDSA-AES256-SHA", "ECDHE-RSA-AES256-SHA", "DHE-RSA-AES128-SHA256", "DHE-RSA-AES128-SHA", "DHE-RSA-AES256-SHA256", "DHE-RSA-AES256-SHA", "AES128-GCM-SHA256", "AES256-GCM-SHA384", "AES128-SHA256", "AES256-SHA256", "AES128-SHA", "AES256-SHA", "!aNULL", "!eNULL", "!EXPORT", "!DES", "!DSS", "!3DES", "!MD5", "!PSK"]);
    }
    $ctx = \stream_context_get_options($socket);
    if (!empty($ctx['ssl'])) {
        $ctx = $ctx['ssl'];
        $compare = $options;
        $no_SNI_nb_hack = empty($ctx['SNI_nb_hack']);
        unset($ctx['SNI_nb_hack'], $ctx['peer_certificate'], $ctx['SNI_server_name']);
        unset($compare['SNI_nb_hack'], $compare['peer_certificate'], $compare['SNI_server_name']);
        if ($ctx == $compare) {
            return new Success($socket);
        } elseif ($no_SNI_nb_hack) {
            return \Amp\pipe(cryptoDisable($socket), function ($socket) use($options) {
                return cryptoEnable($socket, $options);
            });
        }
    }
    if (isset($options["crypto_method"])) {
        $method = $options["crypto_method"];
        unset($options["crypto_method"]);
    } elseif (PHP_VERSION_ID >= 50600 && PHP_VERSION_ID <= 50606) {
        /** @link https://bugs.php.net/69195 */
        $method = \STREAM_CRYPTO_METHOD_TLS_CLIENT;
    } else {
        // note that this constant actually means "Any TLS version EXCEPT SSL v2 and v3"
        $method = \STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
    }
    $options["SNI_nb_hack"] = false;
    \stream_context_set_option($socket, ["ssl" => $options]);
    return $isLegacy ? \Amp\resolve(__watchCryptoLegacy($method, $socket)) : __watchCrypto($method, $socket);
}
コード例 #25
0
ファイル: Info.php プロジェクト: sam002/yii2-acme
 /**
  * @return mixed
  * @throws \Throwable
  */
 public function info()
 {
     return \Amp\wait(\Amp\resolve($this->doInfo()));
 }