implement lets-encrypt api-v02 (testing only currently; not activated in froxlor, test with 'php froxlor_master_cronjob.php --letsencrypt_v2 --debug' but set api endpoint to staging); no chain is returned currently, seems to be a known bug

Signed-off-by: Michael Kaufmann (d00p) <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann (d00p)
2018-01-09 14:40:36 +01:00
parent 3969ef63c5
commit 9aaadb1f8b
3 changed files with 898 additions and 68 deletions

View File

@@ -30,7 +30,6 @@ class lescript
{
// https://letsencrypt.org/repository/
public $license;
private $logger;
@@ -111,19 +110,7 @@ class lescript
}
$accountUrl=$this->client->getLastLocation();
$this->log('Accepting lets encrypt Terms of Service');
$this->license = $this->client->getAgreementURL();
// Terms of Service are optional according to ACME specs; if no ToS are presented, no need to update registration
if (!empty($this->license)) {
$response = $this->postRegAgreement(parse_url($accountUrl, PHP_URL_PATH));
if ($this->client->getLastCode() != 202) {
throw new \RuntimeException("Terms of Service not accepted. Whole response: " . json_encode($response));
}
}
$leregistered=1;
$leregistered = 1;
$this->setLeRegisteredState($leregistered); // Account registered
$this->log('Lets encrypt Terms of Service accepted');
}
@@ -373,21 +360,16 @@ class lescript
private function postNewReg()
{
$this->log('Getting last terms of service URL');
$directory = $this->client->get('/directory');
if (!isset($directory['meta']) || !isset($directory['meta']['terms-of-service'])) {
throw new \RuntimeException("No terms of service link available!");
}
$this->log('Sending registration to letsencrypt server');
return $this->signedRequest('/acme/new-reg', array(
'resource' => 'new-reg',
'agreement' => $this->license
));
}
private function postRegAgreement($uri)
{
$this->log('Accepting agreement at URL: ' . $this->license);
return $this->signedRequest($uri, array(
'resource' => 'reg',
'agreement' => $this->license
'agreement' => $directory['meta']['terms-of-service']
));
}
@@ -592,49 +574,6 @@ class Client
preg_match_all('~Link: <(.+)>;rel="up"~', $this->lastHeader, $matches);
return $matches[1];
}
public function getAgreementURLFromLastResponse()
{
if (preg_match_all('~Link: <(.+)>;rel="terms-of-service"~', $this->lastHeader, $matches)) {
return $matches[1][0];
}
return "";
}
public function getAgreementURLFromDirectory()
{
// FIXME: Current license should be found in /directory but LE does not implement this yet
// $this->curl('GET', '/directory');
return "";
}
public function getAgreementURLFromTermsUrl()
{
$this->curl('GET', '/terms');
if (preg_match_all('~Location: (.+)~', $this->lastHeader, $matches)) {
return trim($matches[1][0]);
}
return "";
}
public function getAgreementURL()
{
// 1. check the header of the last response
$license=$this->getAgreementURLFromLastResponse();
if (!empty($license)) return $license;
// 2. query directory for license
$license=$this->getAgreementURLFromDirectory();
if (!empty($license)) return $license;
// 3. query /terms endpoint (not ACME standard but implemented by let's enrypt)
$license=$this->getAgreementURLFromTermsUrl();
if (!empty($license)) return $license;
// Fallback: use latest known license. This is only valid for let's encrypt and should be removed as soon as there is an official
// ACME-endpoint to get the current ToS
return "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf";
// return "";
}
}
class Base64UrlSafeEncoder