Esempio n. 1
0
 /**
  * @param Manager $args
  * @return \Generator
  */
 private function doExecute(Manager $args)
 {
     $server = \Kelunik\AcmeClient\resolveServer($args->get("server"));
     $server = \Kelunik\AcmeClient\serverToKeyname($server);
     $path = \Kelunik\AcmeClient\normalizePath($args->get("storage")) . "/certs/" . $server;
     $certificateStore = new CertificateStore($path);
     try {
         $pem = (yield $certificateStore->get($args->get("name")));
     } catch (CertificateStoreException $e) {
         $this->climate->br()->error("    Certificate not found.")->br();
         (yield new CoroutineResult(1));
         return;
     }
     $cert = new Certificate($pem);
     $this->climate->br();
     $this->climate->whisper("    Certificate is valid until " . date("d.m.Y", $cert->getValidTo()))->br();
     if ($args->defined("names")) {
         $names = array_map("trim", explode(",", $args->get("names")));
         $missingNames = array_diff($names, $cert->getNames());
         if ($missingNames) {
             $this->climate->comment("    The following names are not covered: " . implode(", ", $missingNames))->br();
             (yield new CoroutineResult(1));
             return;
         }
     }
     if ($cert->getValidTo() > time() + $args->get("ttl") * 24 * 60 * 60) {
         (yield new CoroutineResult(0));
         return;
     }
     $this->climate->comment("    Certificate is going to expire within the specified " . $args->get("ttl") . " days.")->br();
     (yield new CoroutineResult(1));
 }
Esempio n. 2
0
 private function doExecute(Manager $args) : Generator
 {
     if (posix_geteuid() !== 0) {
         throw new AcmeException("Please run this script as root!");
     }
     $server = $args->get("server");
     $protocol = substr($server, 0, strpos("://", $server));
     if (!$protocol || $protocol === $server) {
         $server = "https://" . $server;
     } elseif ($protocol !== "https") {
         throw new \InvalidArgumentException("Invalid server protocol, only HTTPS supported");
     }
     $keyPair = $this->checkRegistration($args);
     $acme = new AcmeService(new AcmeClient($server, $keyPair), $keyPair);
     $this->logger->info("Revoking certificate ...");
     $pem = (yield get($args->get("cert")));
     $cert = new Certificate($pem);
     if ($cert->getValidTo() < time()) {
         $this->logger->warning("Certificate did already expire, no need to revoke it.");
         return;
     }
     $this->logger->info("Certificate was valid for: " . implode(", ", $cert->getNames()));
     (yield $acme->revokeCertificate($pem));
     $this->logger->info("Certificate has been revoked.");
 }
Esempio n. 3
0
 private function doPut(array $certificates)
 {
     if (empty($certificates)) {
         throw new InvalidArgumentException("Empty array not allowed");
     }
     $cert = new Certificate($certificates[0]);
     $commonName = $cert->getSubject()->getCommonName();
     if (!$commonName) {
         throw new CertificateStoreException("Certificate doesn't have a common name.");
     }
     // See https://github.com/amphp/dns/blob/4c4d450d4af26fc55dc56dcf45ec7977373a38bf/lib/functions.php#L83
     if (isset($commonName[253]) || !preg_match("~^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9]){0,1})(?:\\.[a-z0-9][a-z0-9-]{0,61}[a-z0-9])*\$~i", $commonName)) {
         throw new CertificateStoreException("Invalid common name: '{$commonName}'");
     }
     try {
         $chain = array_slice($certificates, 1);
         $path = $this->root . "/" . $commonName;
         $realpath = realpath($path);
         if (!$realpath && !mkdir($path, 0775, true)) {
             throw new FilesystemException("Couldn't create certificate directory: '{$path}'");
         }
         (yield \Amp\File\put($path . "/cert.pem", $certificates[0]));
         (yield \Amp\File\chmod($path . "/cert.pem", 0644));
         (yield \Amp\File\put($path . "/fullchain.pem", implode("\n", $certificates)));
         (yield \Amp\File\chmod($path . "/fullchain.pem", 0644));
         (yield \Amp\File\put($path . "/chain.pem", implode("\n", $chain)));
         (yield \Amp\File\chmod($path . "/chain.pem", 0644));
     } catch (FilesystemException $e) {
         throw new CertificateStoreException("Couldn't save certificates for '{$commonName}'", 0, $e);
     }
 }
Esempio n. 4
0
 private function doExecute(Manager $args)
 {
     $keyStore = new KeyStore(\Kelunik\AcmeClient\normalizePath($args->get("storage")));
     $server = \Kelunik\AcmeClient\resolveServer($args->get("server"));
     $keyFile = \Kelunik\AcmeClient\serverToKeyname($server);
     $keyPair = (yield $keyStore->get("accounts/{$keyFile}.pem"));
     $acme = $this->acmeFactory->build($server, $keyPair);
     $this->climate->br();
     $this->climate->whisper("    Revoking certificate ...");
     $path = \Kelunik\AcmeClient\normalizePath($args->get("storage")) . "/certs/" . $keyFile . "/" . $args->get("name") . "/cert.pem";
     try {
         $pem = (yield \Amp\File\get($path));
         $cert = new Certificate($pem);
     } catch (FilesystemException $e) {
         throw new \RuntimeException("There's no such certificate (" . $path . ")");
     }
     if ($cert->getValidTo() < time()) {
         $this->climate->comment("    Certificate did already expire, no need to revoke it.");
     }
     $names = $cert->getNames();
     $this->climate->whisper("    Certificate was valid for " . count($names) . " domains.");
     $this->climate->whisper("     - " . implode(PHP_EOL . "     - ", $names) . PHP_EOL);
     (yield $acme->revokeCertificate($pem));
     $this->climate->br();
     $this->climate->info("    Certificate has been revoked.");
     (yield (new CertificateStore(\Kelunik\AcmeClient\normalizePath($args->get("storage")) . "/certs/" . $keyFile))->delete($args->get("name")));
     (yield new CoroutineResult(0));
 }
Esempio n. 5
0
 /**
  * @param Manager $args
  * @return \Generator
  */
 private function doExecute(Manager $args)
 {
     $server = \Kelunik\AcmeClient\resolveServer($args->get("server"));
     $keyName = \Kelunik\AcmeClient\serverToKeyname($server);
     $storage = \Kelunik\AcmeClient\normalizePath($args->get("storage"));
     try {
         $keyStore = new KeyStore($storage);
         (yield $keyStore->get("accounts/{$keyName}.pem"));
         $setup = true;
     } catch (KeyStoreException $e) {
         $setup = false;
     }
     $this->climate->br();
     $this->climate->out("  [" . ($setup ? "<green> ✓ </green>" : "<red> ✗ </red>") . "] " . ($setup ? "Registered on " : "Not yet registered on ") . $server);
     $this->climate->br();
     if ((yield \Amp\File\exists($storage . "/certs/{$keyName}"))) {
         $certificateStore = new CertificateStore($storage . "/certs/{$keyName}");
         $domains = (yield \Amp\File\scandir($storage . "/certs/{$keyName}"));
         foreach ($domains as $domain) {
             $pem = (yield $certificateStore->get($domain));
             $cert = new Certificate($pem);
             $symbol = time() > $cert->getValidTo() ? "<red> ✗ </red>" : "<green> ✓ </green>";
             if (time() < $cert->getValidTo() && time() + $args->get("ttl") * 24 * 60 * 60 > $cert->getValidTo()) {
                 $symbol = "<yellow> ⭮ </yellow>";
             }
             $this->climate->out("  [" . $symbol . "] " . implode(", ", $cert->getNames()));
         }
         $this->climate->br();
     }
 }
 /**
  * @param array $certificates
  * @return boolean
  * @throws InvalidParamException
  */
 public function put($certificates = [])
 {
     $cert = new Certificate($certificates[0]);
     $commonName = $cert->getSubject()->getCommonName();
     if (!$commonName) {
         throw new InvalidParamException("Certificate doesn't have a common name.");
     }
     // See https://github.com/amphp/dns/blob/4c4d450d4af26fc55dc56dcf45ec7977373a38bf/lib/functions.php#L83
     if (isset($commonName[253]) || !preg_match("~^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9]){0,1})(?:\\.[a-z0-9][a-z0-9-]{0,61}[a-z0-9])*\$~i", $commonName)) {
         throw new InvalidParamException("Invalid common name: '{$commonName}'");
     }
     $chain = array_slice($certificates, 1);
     file_put_contents($this->getFileName(self::FILE_CERT), $certificates);
     $result = chmod($this->getFileName(self::FILE_CERT), 0644);
     file_put_contents($this->getFileName(self::FILE_FULLCHAIN), implode(PHP_EOL, array_merge($chain)));
     $result &= chmod($this->getFileName(self::FILE_FULLCHAIN), 0644);
     file_put_contents($this->getFileName(self::FILE_CHAIN), implode(PHP_EOL, $chain));
     $result &= chmod($this->getFileName(self::FILE_CHAIN), 0644);
     return $result;
 }
Esempio n. 7
0
 private function certificateInfo(Certificate $certificate, $ttl = 0)
 {
     $isExpired = time() > $certificate->getValidTo();
     $colorExpired = !$isExpired ? Console::FG_GREEN : Console::FG_RED;
     $this->stdout("\n");
     $this->stdout("Certificate ", Console::BOLD);
     $this->stdout("{$certificate->getSubject()->getCommonName()}\n", $colorExpired);
     $this->stdout("Domains :");
     $this->stdout(join(',', $certificate->getNames()) . "\n", Console::ITALIC);
     $this->stdout("Issued by: {$certificate->getIssuer()->getCommonName()}\n");
     $dateFrom = Yii::$app->formatter->asDatetime($certificate->getValidFrom(), 'medium');
     $this->stdout("Valid from: {$dateFrom}\n");
     $dateTo = Yii::$app->formatter->asDatetime($certificate->getValidTo(), 'medium');
     $this->stdout("Valid to: {$dateTo}\n", $colorExpired);
     if (!$isExpired && $ttl > 0) {
         $colorDateDiff = time() + $ttl * 24 * 60 * 60 < $certificate->getValidTo() ? Console::FG_GREEN : Console::FG_YELLOW;
         $dateDiff = Yii::$app->formatter->asRelativeTime($certificate->getValidTo(), $certificate->getValidFrom());
         $this->stdout("Valid time left: {$dateDiff}\n", $colorDateDiff);
     }
 }