kelunik/acme

Discrepancy between master and latest release

prewk opened this issue ยท 15 comments

prewk commented

Hi, I really need the "namshi/jose": "^7", constraint from master that isn't present in the latest release 0.3.3.

Is there a good reason why you haven't released the changes yet?

Thanks!

Mostly time to finish some changes I planned. I can release v0.4.0 anyway and will add those features in v0.5.0 which will be based on Amp v2 then.

prewk commented

That'd be great!

Just because I'm curious: Where are you using the library?

prewk commented

We're implementing HTTPS for our customers in a multi-tenant CMS. Our general idea is that some PHP workers are going to create and refresh the certs. Your library is the only one I've found suitable for PHP, although we won't be running stuff in async.

If we're not successful, we'll probably just wrap one of the CLI clients instead, though.

Not running stuff in async is totally fine, I just wrote it in async so it can be used, e.g. in Aerys to automatically issue and renew certificates.

You could also just wrap https://github.com/kelunik/acme-client, yes, but then you could also wrap any other CLI client.

v0.4.0 has been released. ๐ŸŽ‰

prewk commented

Are you up for answering some simple questions about the process? I might be misunderstanding how the manual Let's Encrypt process works so it's okay to yell at me if that's the case, but I've dug around as much as I could and can't get further.

The process as I've imagined it:

// Trying the staging url but the production url gives me the same results
$directoryUri = "https://acme-staging.api.letsencrypt.org/directory";
  1. $key = $keyGenerator->generate()
  2. $service = new AcmeService(new AcmeClient($directoryUri, $key))
  3. $challenges = $service->requestChallenges("www.my-domain.com") (Shouldn't I provide a key here somehow?)
  4. $challenges contains some challenge types with tokens and uris. I pluck out the http-01 one.
  5. $keyAuth = generateKeyAuthorization($key, $challengeToken)
  6. I make sure www.my-domain.com/.well-known/acme-challenge/$challengeToken returns ?????? (Do I receive this JSON blob in step 3?)
  7. $answered = $service->answerChallenge($challengeUri, $keyAuth)
  8. $service->pollForChallenge($challengeUri) until validated/failed
  9. How do I generate a CSR using the service?
  10. $certUri = $service->requestCertificate($csr)
  11. $certChain = $service->pollForCertificate($certUri)

$certChain should now be a certificate chain. Is this somewhat correct?

Problem is right now that, everytime I try to do a requestChallenges I get this error:

Invalid response: No registration exists matching provided key.
Request URI: https://acme-staging.api.letsencrypt.org/acme/new-authz.

Thanks a bunch. I understand you can't be expected to give detailed Let's Encrypt support, but any pointers would help.

Yes, that's pretty much right.

  • The step you forgot is the account registration with the account key (that's the initial key you generated). You can use AcmeService::register() for that.
  • Step 8 can be done with the CSRGenerator.
  • The key you're missing for step 3 has been provided in step 2.
  • ?????? in step 6 is the $keyAuth generated in step 5.

If you don't want to use async, you can wrap the calls in Amp\wait, otherwise I'd recommend using a coroutine and yield to await the promises returned from the methods.

prewk commented

Thanks, this helped me a lot!

prewk commented

One final thing, which certificate in the chain is "the one" for my requested DNS name? First? Last?

I'm going to import them into AWS ACM, so I need both "the certificate" and "the chain".

prewk commented

I'm struggling a bit with OpenSSLCSRGenerator->generate. The docs say that it returns a promise, but Amp\wait doesn't seem to work with it: Type error: Argument 1 passed to Amp\wait() must implement interface Amp\Promise, instance of Generator given

So I'm thinking, I should turn this generator into a Promise with Amp\resolve first. This seems to work, but the result from the generate method is a bool true instead of a string CSR.

So I dig into the OpenSSLCSRGenerator source and find: yield new CoroutineResult(openssl_csr_export($csr, $csr));.

It seems to be returning the result of openssl_scr_export which is always a bool (http://se2.php.net/manual/en/function.openssl-csr-export.php), instead of the &out ref argument that openssl_scr_export writes to (weird old C API, I suppose).

Yes, I also noticed that earlier today while rewriting the library to Amp v2. Want to provide a PR that fixes it?

prewk commented

Gladly! I'll do one tomorrow.