/** * {@inheritdoc} */ public function requestCertificate($domain, CertificateRequest $csr, $timeout = 180) { Assert::stringNotEmpty($domain, 'requestCertificate::$domain expected a non-empty string. Got: %s'); Assert::integer($timeout, 'requestCertificate::$timeout expected an integer. Got: %s'); $humanText = ['-----BEGIN CERTIFICATE REQUEST-----', '-----END CERTIFICATE REQUEST-----']; $csrContent = $this->csrSigner->signCertificateRequest($csr); $csrContent = trim(str_replace($humanText, '', $csrContent)); $csrContent = trim($this->httpClient->getBase64Encoder()->encode(base64_decode($csrContent))); $response = $this->requestResource('POST', ResourcesDirectory::NEW_CERTIFICATE, ['resource' => ResourcesDirectory::NEW_CERTIFICATE, 'csr' => $csrContent], false); // If the CA has not yet issued the certificate, the body of this response will be empty if (strlen(trim($response)) < 10) { // 10 to avoid false results $location = $this->httpClient->getLastLocation(); // Waiting loop $endTime = time() + $timeout; while (time() <= $endTime) { $response = $this->httpClient->unsignedRequest('GET', $location, null, false); if (200 === $this->httpClient->getLastCode()) { break; } if (202 !== $this->httpClient->getLastCode()) { throw new CertificateRequestFailedException($response); } sleep(1); } if (202 === $this->httpClient->getLastCode()) { throw new CertificateRequestTimedOutException($response); } } // Find issuers certificate $links = $this->httpClient->getLastLinks(); $certificatesChain = null; foreach ($links as $link) { if (!isset($link['rel']) || 'up' !== $link['rel']) { continue; } $location = trim($link[0], '<>'); $certificate = $this->httpClient->unsignedRequest('GET', $location, null, false); if (strlen(trim($certificate)) > 10) { $pem = chunk_split(base64_encode($certificate), 64, "\n"); $pem = "-----BEGIN CERTIFICATE-----\n" . $pem . "-----END CERTIFICATE-----\n"; $certificatesChain = new Certificate($pem, $certificatesChain); } } // Domain certificate $pem = chunk_split(base64_encode($response), 64, "\n"); $pem = "-----BEGIN CERTIFICATE-----\n" . $pem . "-----END CERTIFICATE-----\n"; return new CertificateResponse($csr, new Certificate($pem, $certificatesChain)); }