acme-client 2.0.7 → 2.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 718dac85c8139621711a030272097498d04414ca52c9d84544b8bac32179e8a1
4
- data.tar.gz: 9e929450733261f291a62b96f5056ed89e8c235cae010805ddccfc3efb17188c
3
+ metadata.gz: 9cb714bd4f0321181c50087f976122251233340d09f4ed612cf91070e0986d70
4
+ data.tar.gz: db7df58ad9a1e4794bef25dfbc309efad73b9b1cbb6100f77d9552cbb734fb5d
5
5
  SHA512:
6
- metadata.gz: f6e77c41a67b3f2fe9d6e373d58e928bfc0ee2523ac7b0ce2beb93167179a0950045cbb0ec4f5d8616527108814001acd0da7909a8bb0df8dac9b6ddde8bfbba
7
- data.tar.gz: 9eba181b543cfe437e2043970b2e74cd691944457d43d3c3ea052cf10d3134e59b51aa8ee3522c36f27b25c212797e44e0e29b86f96b13361e98ca07d054ccac
6
+ metadata.gz: 8d7eb7d76ea95ab724810af93ad4e79af03fe62752509a793b5310b01b670b7c57f737bbb3a68de72ab4e84f01f9d613e45937a50119ddfe3b0f5d0aa628f45e
7
+ data.tar.gz: 38b349fdcdb68f5ec493951ec4a480966256e591f6d9cffc4266116bff6d2aed6e8f0e5493acf985f6a81c0cad7c20a69e4d7bd1cedb95357b297cdcfb1b494c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## `2.0.8`
2
+
3
+ * Add support for the keyChange endpoint
4
+
5
+ https://tools.ietf.org/html/rfc8555#section-7.3.5
6
+
7
+
1
8
  ## `2.0.7`
2
9
 
3
10
  * Add support for alternate certificate chain
data/README.md CHANGED
@@ -23,17 +23,26 @@ gem 'acme-client'
23
23
  ```
24
24
 
25
25
  ## Usage
26
- * [Setting up a client](#setting-up-a-client)
27
- * [Account management](#account-management)
28
- * [Obtaining a certificate](#obtaining-a-certificate)
29
- * [Ordering a certificate](#ordering-a-certificate)
30
- * [Completing an HTTP challenge](#preparing-for-http-challenge)
31
- * [Completing an DNS challenge](#preparing-for-dns-challenge)
32
- * [Requesting a challenge verification](#requesting-a-challenge-verification)
33
- * [Downloading a certificate](#downloading-a-certificate)
34
- * [Extra](#extra)
35
- * [Certificate revokation](#certificate-revokation)
36
- * [Certificate renewal](#certificate-renewal)
26
+ - [Acme::Client](#acmeclient)
27
+ - [Installation](#installation)
28
+ - [Usage](#usage)
29
+ - [Setting up a client](#setting-up-a-client)
30
+ - [Account management](#account-management)
31
+ - [Obtaining a certificate](#obtaining-a-certificate)
32
+ - [Ordering a certificate](#ordering-a-certificate)
33
+ - [Preparing for HTTP challenge](#preparing-for-http-challenge)
34
+ - [Preparing for DNS challenge](#preparing-for-dns-challenge)
35
+ - [Requesting a challenge verification](#requesting-a-challenge-verification)
36
+ - [Downloading a certificate](#downloading-a-certificate)
37
+ - [Ordering an alternative certificate](#ordering-an-alternative-certificate)
38
+ - [Extra](#extra)
39
+ - [Certificate revokation](#certificate-revokation)
40
+ - [Certificate renewal](#certificate-renewal)
41
+ - [Not implemented](#not-implemented)
42
+ - [Requirements](#requirements)
43
+ - [Development](#development)
44
+ - [Pull request?](#pull-request)
45
+ - [License](#license)
37
46
 
38
47
  ## Setting up a client
39
48
 
@@ -91,7 +100,7 @@ account.kid # => <kid string>
91
100
 
92
101
  If you already have an existing account (for example one created in ACME v1) please note that unless the `kid` is provided at initialization, the client will lazy load the `kid` by doing a `POST` to `newAccount` whenever the `kid` is required. Therefore, you can easily get your `kid` for an existing account and (if needed) store it for reuse:
93
102
 
94
- ```
103
+ ```ruby
95
104
  client = Acme::Client.new(private_key: private_key, directory: 'https://acme-staging-v02.api.letsencrypt.org/directory')
96
105
 
97
106
  # kid is not set, therefore a call to newAccount is made to lazy-initialize the kid
@@ -189,6 +198,23 @@ end
189
198
  order.certificate # => PEM-formatted certificate
190
199
  ```
191
200
 
201
+ ### Ordering an alternative certificate
202
+
203
+ Let's Encrypt is [transitioning](https://letsencrypt.org/2019/04/15/transitioning-to-isrg-root.html) to use a new intermediate certificate. Starting January 11, 2021 new certificates will be signed by their own intermediate. To ease the transition on clients Let's Encrypt will continue signing an alternative version of the certificate using the old, cross-signed intermediate until September 29, 2021. In order to utilize an alternative certificate the `Order#certificate` method accepts a `force_chain` keyword argument, which takes the issuer name of the intermediate certificate.
204
+ For example, to download the cross-signed certificate after January 11, 2021, call `Order#certificate` as follows:
205
+
206
+ ```ruby
207
+ begin
208
+ order.certificate(force_chain: 'DST Root CA X3')
209
+ rescue Acme::Client::Error::ForcedChainNotFound
210
+ order.certificate
211
+ end
212
+ ```
213
+
214
+ Note: if the specified forced chain doesn't match an existing alternative certificate the method will raise an `Acme::Client::Error::ForcedChainNotFound` error.
215
+
216
+ Learn more about the original Github issue for this client [here](https://github.com/unixcharles/acme-client/issues/186), information from Let's Encrypt [here](https://letsencrypt.org/2019/04/15/transitioning-to-isrg-root.html), and cross-signing [here](https://letsencrypt.org/certificates/#cross-signing).
217
+
192
218
  ## Extra
193
219
 
194
220
  ### Certificate revokation
@@ -204,9 +230,15 @@ client.revoke(certificate: certificate)
204
230
  There is no renewal process, just create a new order.
205
231
 
206
232
 
207
- ## Not implemented
233
+ ### Account Key Roll-over
208
234
 
209
- - Account Key Roll-over.
235
+ To change the key used for an account you can call `#account_key_change` with the new private key or jwk.
236
+
237
+ ```ruby
238
+ require 'openssl'
239
+ new_private_key = OpenSSL::PKey::RSA.new(4096)
240
+ client.account_key_change(private_key: new_private_key)
241
+ ```
210
242
 
211
243
  ## Requirements
212
244
 
@@ -227,4 +259,3 @@ Yes.
227
259
  ## License
228
260
 
229
261
  [MIT License](http://opensource.org/licenses/MIT)
230
-
data/lib/acme/client.rb CHANGED
@@ -85,6 +85,28 @@ class Acme::Client
85
85
  Acme::Client::Resources::Account.new(self, url: kid, **arguments)
86
86
  end
87
87
 
88
+ def account_key_change(new_private_key: nil, new_jwk: nil)
89
+ if new_private_key.nil? && new_jwk.nil?
90
+ raise ArgumentError, 'must specify new_jwk or new_private_key'
91
+ end
92
+ old_jwk = jwk
93
+ new_jwk ||= Acme::Client::JWK.from_private_key(new_private_key)
94
+
95
+ inner_payload_header = {
96
+ url: endpoint_for(:key_change)
97
+ }
98
+ inner_payload = {
99
+ account: kid,
100
+ oldKey: old_jwk.to_h
101
+ }
102
+ payload = JSON.parse(new_jwk.jws(header: inner_payload_header, payload: inner_payload))
103
+
104
+ response = post(endpoint_for(:key_change), payload: payload, mode: :kid)
105
+ arguments = attributes_from_account_response(response)
106
+ @jwk = new_jwk
107
+ Acme::Client::Resources::Account.new(self, url: kid, **arguments)
108
+ end
109
+
88
110
  def account
89
111
  @kid ||= begin
90
112
  response = post(endpoint_for(:new_account), payload: { onlyReturnExisting: true }, mode: :jwk)
@@ -73,8 +73,10 @@ class Acme::Client::JWK::ECDSA < Acme::Client::JWK::Base
73
73
  # BigNumbers
74
74
  bns = ints.map(&:value)
75
75
 
76
+ byte_size = (@private_key.group.degree + 7) / 8
77
+
76
78
  # Binary R/S values
77
- r, s = bns.map { |bn| [bn.to_s(16)].pack('H*') }
79
+ r, s = bns.map { |bn| bn.to_s(2).rjust(byte_size, "\x00") }
78
80
 
79
81
  # JWS wants raw R/S concatenated.
80
82
  [r, s].join
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Acme
4
4
  class Client
5
- VERSION = '2.0.7'.freeze
5
+ VERSION = '2.0.8'.freeze
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acme-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7
4
+ version: 2.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Barbier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-18 00:00:00.000000000 Z
11
+ date: 2021-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler