#5 Sticky: ACME v2 (now available)

Closed
opened 1 year ago by Noim · 4 comments
Noim commented 1 year ago

Hello,

does greenlock support ACME v2. The last update is already a few month ago, so I assume it does not.

Any Plans to support it?

https://community.letsencrypt.org/t/acme-v2-production-environment-wildcards/55578

Greetings Nils

Hello, does greenlock support ACME v2. The last update is already a few month ago, so I assume it does not. Any Plans to support it? https://community.letsencrypt.org/t/acme-v2-production-environment-wildcards/55578 Greetings Nils
coolaj86 commented 1 year ago
Owner

Landed in v2.2.4

git clone https://git.coolaj86.com/coolaj86/greenlock.js.git

or

npm install greenlock@latest

Not yet. I’m looking into it and I would love help.

Landed in v2.2.4 ================ ```bash git clone https://git.coolaj86.com/coolaj86/greenlock.js.git ``` or ```bash npm install greenlock@latest ``` ~~Not yet. I'm looking into it and I would love help.~~
coolaj86 commented 1 year ago
Owner

According to that document this is the latest draft of the standard:

https://tools.ietf.org/html/draft-ietf-acme-acme-10

This is the new directory URL:

https://acme-staging-v02.api.letsencrypt.org/directory

I’m trying to understand what the technical differences are between the old implementation and the new.

I do know that only http and dns challenges will be supported at present.

Updated flow (in section 7.1):

                                  directory
                                      |
                                      +--> newNonce
                                      |
          +----------+----------+-----+-----+------------+
          |          |          |           |            |
          |          |          |           |            |
          V          V          V           V            V
     newAccount   newAuthz   newOrder   revokeCert   keyChange
          |          |          |
          |          |          |
          V          |          V
       account       |        order -----> finalize
                     |          |   -----> cert
                     |          |
                     |          V
                     +---> authorizations
                               | ^
                               | | "up"
                               V |
                             challenge
   +-----------------------+--------------------------+----------------+
   | Action                | Request                  | Response       |
   +-----------------------+--------------------------+----------------+
   | Get directory         | GET  directory           | 200            |
   |                       |                          |                |
   | Get nonce             | HEAD newNonce            | 200            |
   |                       |                          |                |
   | Create account        | POST newAccount          | 201 -> account |
   |                       |                          |                |
   | Submit order          | POST newOrder            | 201 -> order   |
   |                       |                          |                |
   | Fetch challenges      | GET  order               | 200            |
   |                       | authorizations           |                |
   |                       |                          |                |
   | Respond to challenges | POST challenge urls      | 200            |
   |                       |                          |                |
   | Finalize order        | POST order finalize      | 200            |
   |                       |                          |                |
   | Poll for status       | GET  order               | 200            |
   |                       |                          |                |
   | Download certificate  | GET  order cert          | 200            |
   +-----------------------+--------------------------+----------------+

The ACME v1 protocol library is here https://git.coolaj86.com/coolaj86/le-acme-core.js

I’m building out the ACME v2 library here https://git.coolaj86.com/coolaj86/acme-v2.js

Create Account

   POST /acme/new-account HTTP/1.1
   Host: example.com
   Content-Type: application/jose+json

   {
     "protected": base64url({
       "alg": "ES256",
       "jwk": {...},
       "nonce": "6S8IqOGY7eL2lsGoTZYifg",
       "url": "https://example.com/acme/new-account"
     }),
     "payload": base64url({
       "termsOfServiceAgreed": true,
       "contact": [
         "mailto:cert-admin@example.com",
         "mailto:admin@example.com"
       ]
     }),
     "signature": "RZPOnYoPs1PhjszF...-nh6X1qtOFPB519I"
   }

Create Authorization

   POST /acme/new-authz HTTP/1.1
   Host: example.com
   Content-Type: application/jose+json

   {
     "protected": base64url({
       "alg": "ES256",
       "kid": "https://example.com/acme/acct/1",
       "nonce": "uQpSjlRb4vQVCjVYAyyUWg",
       "url": "https://example.com/acme/new-authz"
     }),
     "payload": base64url({
       "identifier": {
         "type": "dns",
         "value": "example.net"
       }
     }),
     "signature": "nuSDISbWG8mMgE7H...QyVUL68yzf3Zawps"
   }

New Order 7.4. Applying for Certificate Issuance

   POST /acme/new-order HTTP/1.1
   Host: example.com
   Content-Type: application/jose+json

   {
     "protected": base64url({
       "alg": "ES256",
       "kid": "https://example.com/acme/acct/1",
       "nonce": "5XJ1L3lEkMG7tR6pA00clA",
       "url": "https://example.com/acme/new-order"
     }),
     "payload": base64url({
       "identifiers": [{"type:"dns","value":"example.com"}],
       "notBefore": "2016-01-01T00:00:00Z",
       "notAfter": "2016-01-08T00:00:00Z"
     }),
     "signature": "H6ZXtGjTZyUnPeKn...wEA4TklBdh3e454g"
   }

Respond to Challenges 7.5.1. Responding to Challenges

   POST /acme/authz/1234/0 HTTP/1.1
   Host: example.com
   Content-Type: application/jose+json

   {
     "protected": base64url({
       "alg": "ES256",
       "kid": "https://example.com/acme/acct/1",
       "nonce": "Q_s3MWoqT05TrdkM2MTDcw",
       "url": "https://example.com/acme/authz/1234/0"
     }),
     "payload": base64url({}),
     "signature": "9cbg5JO1Gf5YLjjz...SpkUfcdPai9uVYYQ"
   }

HTTP-01 7.5.1. Responding to Challenges

//   keyAuthorization = token || '.' || base64url(JWK_Thumbprint(accountKey))
//   GET /.well-known/acme-challenge/:token

//   Must return {{ keyAuthorization }} as text

Key Authorization:

  keyAuthorization = token || '.' || base64url(JWK_Thumbprint(accountKey))
According to that document this is the latest draft of the standard: https://tools.ietf.org/html/draft-ietf-acme-acme-10 This is the new directory URL: https://acme-staging-v02.api.letsencrypt.org/directory I'm trying to understand what the technical differences are between the old implementation and the new. I do know that only http and dns challenges will be supported at present. Updated flow (in section 7.1): ``` directory | +--> newNonce | +----------+----------+-----+-----+------------+ | | | | | | | | | | V V V V V newAccount newAuthz newOrder revokeCert keyChange | | | | | | V | V account | order -----> finalize | | -----> cert | | | V +---> authorizations | ^ | | "up" V | challenge ``` ``` +-----------------------+--------------------------+----------------+ | Action | Request | Response | +-----------------------+--------------------------+----------------+ | Get directory | GET directory | 200 | | | | | | Get nonce | HEAD newNonce | 200 | | | | | | Create account | POST newAccount | 201 -> account | | | | | | Submit order | POST newOrder | 201 -> order | | | | | | Fetch challenges | GET order | 200 | | | authorizations | | | | | | | Respond to challenges | POST challenge urls | 200 | | | | | | Finalize order | POST order finalize | 200 | | | | | | Poll for status | GET order | 200 | | | | | | Download certificate | GET order cert | 200 | +-----------------------+--------------------------+----------------+ ``` The ACME v1 protocol library is here https://git.coolaj86.com/coolaj86/le-acme-core.js I'm building out the ACME v2 library here https://git.coolaj86.com/coolaj86/acme-v2.js **Create Account** ``` POST /acme/new-account HTTP/1.1 Host: example.com Content-Type: application/jose+json { "protected": base64url({ "alg": "ES256", "jwk": {...}, "nonce": "6S8IqOGY7eL2lsGoTZYifg", "url": "https://example.com/acme/new-account" }), "payload": base64url({ "termsOfServiceAgreed": true, "contact": [ "mailto:cert-admin@example.com", "mailto:admin@example.com" ] }), "signature": "RZPOnYoPs1PhjszF...-nh6X1qtOFPB519I" } ``` **Create Authorization** ``` POST /acme/new-authz HTTP/1.1 Host: example.com Content-Type: application/jose+json { "protected": base64url({ "alg": "ES256", "kid": "https://example.com/acme/acct/1", "nonce": "uQpSjlRb4vQVCjVYAyyUWg", "url": "https://example.com/acme/new-authz" }), "payload": base64url({ "identifier": { "type": "dns", "value": "example.net" } }), "signature": "nuSDISbWG8mMgE7H...QyVUL68yzf3Zawps" } ``` **New Order** 7.4. Applying for Certificate Issuance ``` POST /acme/new-order HTTP/1.1 Host: example.com Content-Type: application/jose+json { "protected": base64url({ "alg": "ES256", "kid": "https://example.com/acme/acct/1", "nonce": "5XJ1L3lEkMG7tR6pA00clA", "url": "https://example.com/acme/new-order" }), "payload": base64url({ "identifiers": [{"type:"dns","value":"example.com"}], "notBefore": "2016-01-01T00:00:00Z", "notAfter": "2016-01-08T00:00:00Z" }), "signature": "H6ZXtGjTZyUnPeKn...wEA4TklBdh3e454g" } ``` **Respond to Challenges** 7.5.1. Responding to Challenges ``` POST /acme/authz/1234/0 HTTP/1.1 Host: example.com Content-Type: application/jose+json { "protected": base64url({ "alg": "ES256", "kid": "https://example.com/acme/acct/1", "nonce": "Q_s3MWoqT05TrdkM2MTDcw", "url": "https://example.com/acme/authz/1234/0" }), "payload": base64url({}), "signature": "9cbg5JO1Gf5YLjjz...SpkUfcdPai9uVYYQ" } ``` **HTTP-01** 7.5.1. Responding to Challenges ``` // keyAuthorization = token || '.' || base64url(JWK_Thumbprint(accountKey)) // GET /.well-known/acme-challenge/:token // Must return {{ keyAuthorization }} as text ``` **Key Authorization**: ``` keyAuthorization = token || '.' || base64url(JWK_Thumbprint(accountKey)) ```
coolaj86 commented 1 year ago
Owner
Good news, I’ve got a very simple hard-coded test working with the v2 API.

:)

The next step will be to match the previous API method names and parameters, if possible. I suspect that the abstract API will be backwards compatible.

https://git.coolaj86.com/coolaj86/acme-v2.js

Good news, I've got a very simple hard-coded test working with the v2 API. :) The next step will be to match the previous API method names and parameters, if possible. I suspect that the abstract API will be backwards compatible. https://git.coolaj86.com/coolaj86/acme-v2.js
coolaj86 commented 1 year ago
Owner

Great news! Let’s Encrypt v2 (ACME draft 11) support has landed and is published on npm!

v2.2.0

It works for me both forwards and backwards compatible. Please try it out and let me know that it works for you.

Great news! Let's Encrypt v2 (ACME draft 11) support has landed and is published on npm! v2.2.0 It works for me both forwards and backwards compatible. Please try it out and let me know that it works for you.
coolaj86 changed title from ACME v2 to Sticky: ACME v2 (now available) 1 year ago
Sign in to join this conversation.
No Label
No Milestone
No Assignees
2 Participants
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
Cancel
Save
There is no content yet.