acme-client 2.0.15 → 2.0.17

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: a634fb4c9a908ebb94e2ace402f7a66f510df3e0b6307b78c2e06eeabdb0e497
4
- data.tar.gz: eb4bbbcc6f4ad0dd055fcb2a7897e408b862251c7e63c3b9c711f175fd21e727
3
+ metadata.gz: 417bc7e66063768660e078a24866ac390792f42c861742054ee4d6269297bb3d
4
+ data.tar.gz: 29d839f6c57f17ca85dcce3bad8b505bf9bc75a7ae4ea5baca55c341b29cf238
5
5
  SHA512:
6
- metadata.gz: abd5644a5d5b6edfaf9e04a9d5fb382efcdbfcde55ce2327ecb21400ec827512fc4dd38fdfcbe67e239d4ce2b848a5677c6406220b8740ad37291e608290c9e2
7
- data.tar.gz: 0f7f4d87df7011f99b2b36064ff13ced4c7d9b2e86ad8dccbb1c52374da9a57044433c7c7a7571a820a678e735d4eb3e1bb9e4d96f3c6c69f183151aeb012d7d
6
+ metadata.gz: b769d1192fcbf7468cea7637a79398d19a1561da94e34e1e08c15108dba6923b2f2c4d38c2a6404699111b42455c97217eec46ba5fbb66c6a0e0661230743b0b
7
+ data.tar.gz: aa3deacd0ad900db154efaf3d6e231faf2b8f8ac01e9a02cfafb4b17f7993e13c8bad00321545b4a042e49ba68540b4be874ca5024828ac0299edf7c47d7c246
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## `2.0.17`
2
+
3
+ * Fix bug where depending on call order `jws` get generated with the wrong `kid`
4
+
5
+ ## `2.0.16`
6
+
7
+ * Refactor Directory
8
+ * Fix an issue where the client would crash when ACME provider return nonce for directory endpoint
9
+
1
10
  ## `2.0.15`
2
11
 
3
12
  * Also pass connection_options to Faraday for Client#get_nonce
data/Gemfile CHANGED
@@ -8,6 +8,5 @@ end
8
8
 
9
9
  group :development, :test do
10
10
  gem 'pry'
11
- gem 'rubocop', '~> 0.49.0'
12
11
  gem 'ruby-prof', require: false
13
12
  end
data/README.md CHANGED
@@ -1,13 +1,11 @@
1
1
  # Acme::Client
2
2
 
3
- `acme-client` is a client implementation of the ACMEv2 / [RFC 8555](https://tools.ietf.org/html/rfc8555) protocol in Ruby.
3
+ `acme-client` is a client implementation of the ACME / [RFC 8555](https://tools.ietf.org/html/rfc8555) protocol in Ruby.
4
4
 
5
5
  You can find the ACME reference implementations of the [server](https://github.com/letsencrypt/boulder) in Go and the [client](https://github.com/certbot/certbot) in Python.
6
6
 
7
7
  ACME is part of the [Letsencrypt](https://letsencrypt.org/) project, which goal is to provide free SSL/TLS certificates with automation of the acquiring and renewal process.
8
8
 
9
- You can find ACMEv1 compatible client in the [acme-v1](https://github.com/unixcharles/acme-client/tree/acme-v1) branch.
10
-
11
9
  ## Installation
12
10
 
13
11
  Via RubyGems:
@@ -207,8 +205,7 @@ order.certificate # => PEM-formatted certificate
207
205
 
208
206
  ### Ordering an alternative certificate
209
207
 
210
- 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.
211
- For example, to download the cross-signed certificate after January 11, 2021, call `Order#certificate` as follows:
208
+ The provider may provide alternate certificate with different certificate chain. You can specify the required chain and the client will automatically download alternate certificate and match the chain by name.
212
209
 
213
210
  ```ruby
214
211
  begin
@@ -249,7 +246,7 @@ client.account_key_change(new_private_key: new_private_key)
249
246
 
250
247
  ## Requirements
251
248
 
252
- Ruby >= 2.1
249
+ Ruby >= 3.0
253
250
 
254
251
  ## Development
255
252
 
data/Rakefile CHANGED
@@ -3,7 +3,4 @@ require 'bundler/gem_tasks'
3
3
  require 'rspec/core/rake_task'
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- require 'rubocop/rake_task'
7
- RuboCop::RakeTask.new
8
-
9
- task default: [:spec, :rubocop]
6
+ task default: [:spec]
data/acme-client.gemspec CHANGED
@@ -16,12 +16,11 @@ Gem::Specification.new do |spec|
16
16
 
17
17
  spec.required_ruby_version = '>= 2.3.0'
18
18
 
19
- spec.add_development_dependency 'bundler', '>= 1.17.3'
20
19
  spec.add_development_dependency 'rake', '~> 13.0'
21
20
  spec.add_development_dependency 'rspec', '~> 3.9'
22
21
  spec.add_development_dependency 'vcr', '~> 2.9'
23
22
  spec.add_development_dependency 'webmock', '~> 3.8'
24
- spec.add_development_dependency 'webrick'
23
+ spec.add_development_dependency 'webrick', '~> 1.7'
25
24
 
26
25
  spec.add_runtime_dependency 'faraday', '>= 1.0', '< 3.0.0'
27
26
  spec.add_runtime_dependency 'faraday-retry', '>= 1.0', '< 3.0.0'
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'acme-client'
5
+
6
+ require File.join(File.dirname(__FILE__), '../spec/support/ssl_helper')
7
+
8
+
9
+ SSLHelper::KEYSTASH.generate_keystash!(size: 200)
@@ -56,7 +56,7 @@ class Acme::Client::Resources::Authorization
56
56
  type: attributes.fetch('type'),
57
57
  status: attributes.fetch('status'),
58
58
  url: attributes.fetch('url'),
59
- token: attributes.fetch('token'),
59
+ token: attributes.fetch('token', nil),
60
60
  error: attributes['error']
61
61
  }
62
62
  Acme::Client::Resources::Challenges.new(@client, **arguments)
@@ -17,12 +17,13 @@ class Acme::Client::Resources::Directory
17
17
  external_account_required: 'externalAccountRequired'
18
18
  }
19
19
 
20
- def initialize(url, connection_options)
21
- @url, @connection_options = url, connection_options
20
+ def initialize(client, **arguments)
21
+ @client = client
22
+ assign_attributes(**arguments)
22
23
  end
23
24
 
24
25
  def endpoint_for(key)
25
- directory.fetch(key) do |missing_key|
26
+ @directory.fetch(key) do |missing_key|
26
27
  raise Acme::Client::Error::UnsupportedOperation,
27
28
  "Directory at #{@url} does not include `#{missing_key}`"
28
29
  end
@@ -45,31 +46,16 @@ class Acme::Client::Resources::Directory
45
46
  end
46
47
 
47
48
  def meta
48
- directory[:meta]
49
+ @directory[:meta]
49
50
  end
50
51
 
51
52
  private
52
53
 
53
- def directory
54
- @directory ||= load_directory
55
- end
56
-
57
- def load_directory
58
- body = fetch_directory
59
- result = {}
60
- result[:meta] = body.delete('meta')
54
+ def assign_attributes(directory:)
55
+ @directory = {}
56
+ @directory[:meta] = directory.delete('meta')
61
57
  DIRECTORY_RESOURCES.each do |key, entry|
62
- result[key] = URI(body[entry]) if body[entry]
58
+ @directory[key] = URI(directory[entry]) if directory[entry]
63
59
  end
64
- result
65
- rescue JSON::ParserError => exception
66
- raise Acme::Client::Error::InvalidDirectory,
67
- "Invalid directory url\n#{@directory} did not return a valid directory\n#{exception.inspect}"
68
- end
69
-
70
- def fetch_directory
71
- http_client = Acme::Client::HTTPClient.new_acme_connection(url: @directory, options: @connection_options, client: nil, mode: nil)
72
- response = http_client.get(@url)
73
- response.body
74
60
  end
75
61
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Acme
4
4
  class Client
5
- VERSION = '2.0.15'.freeze
5
+ VERSION = '2.0.17'.freeze
6
6
  end
7
7
  end
data/lib/acme/client.rb CHANGED
@@ -44,7 +44,7 @@ class Acme::Client
44
44
 
45
45
  @kid, @connection_options = kid, connection_options
46
46
  @bad_nonce_retry = bad_nonce_retry
47
- @directory = Acme::Client::Resources::Directory.new(URI(directory), @connection_options)
47
+ @directory_url = URI(directory)
48
48
  @nonces ||= []
49
49
  end
50
50
 
@@ -229,28 +229,44 @@ class Acme::Client
229
229
  true
230
230
  end
231
231
 
232
+ def directory
233
+ @directory ||= load_directory
234
+ end
235
+
232
236
  def meta
233
- @directory.meta
237
+ directory.meta
234
238
  end
235
239
 
236
240
  def terms_of_service
237
- @directory.terms_of_service
241
+ directory.terms_of_service
238
242
  end
239
243
 
240
244
  def website
241
- @directory.website
245
+ directory.website
242
246
  end
243
247
 
244
248
  def caa_identities
245
- @directory.caa_identities
249
+ directory.caa_identities
246
250
  end
247
251
 
248
252
  def external_account_required
249
- @directory.external_account_required
253
+ directory.external_account_required
250
254
  end
251
255
 
252
256
  private
253
257
 
258
+ def load_directory
259
+ Acme::Client::Resources::Directory.new(self, directory: fetch_directory)
260
+ end
261
+
262
+ def fetch_directory
263
+ response = get(@directory_url)
264
+ response.body
265
+ rescue JSON::ParserError => exception
266
+ raise Acme::Client::Error::InvalidDirectory,
267
+ "Invalid directory url\n#{@directory_url} did not return a valid directory\n#{exception.inspect}"
268
+ end
269
+
254
270
  def prepare_order_identifiers(identifiers)
255
271
  if identifiers.is_a?(Hash)
256
272
  [identifiers]
@@ -316,7 +332,7 @@ class Acme::Client
316
332
  connection.post(url, nil)
317
333
  end
318
334
 
319
- def get(url, mode: :kid)
335
+ def get(url, mode: :get)
320
336
  connection = connection_for(url: url, mode: mode)
321
337
  connection.get(url)
322
338
  end
@@ -340,17 +356,7 @@ class Acme::Client
340
356
  )
341
357
  end
342
358
 
343
- def fetch_chain(response, limit = 10)
344
- links = response.headers['link']
345
- if limit.zero? || links.nil? || links['up'].nil?
346
- []
347
- else
348
- issuer = get(links['up'])
349
- [OpenSSL::X509::Certificate.new(issuer.body), *fetch_chain(issuer, limit - 1)]
350
- end
351
- end
352
-
353
359
  def endpoint_for(key)
354
- @directory.endpoint_for(key)
360
+ directory.endpoint_for(key)
355
361
  end
356
362
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acme-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.15
4
+ version: 2.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Barbier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-06 00:00:00.000000000 Z
11
+ date: 2024-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 1.17.3
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: 1.17.3
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rake
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -84,16 +70,16 @@ dependencies:
84
70
  name: webrick
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
- - - ">="
73
+ - - "~>"
88
74
  - !ruby/object:Gem::Version
89
- version: '0'
75
+ version: '1.7'
90
76
  type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
- - - ">="
80
+ - - "~>"
95
81
  - !ruby/object:Gem::Version
96
- version: '0'
82
+ version: '1.7'
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: faraday
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -148,6 +134,7 @@ files:
148
134
  - Rakefile
149
135
  - acme-client.gemspec
150
136
  - bin/console
137
+ - bin/generate_keystash
151
138
  - bin/release
152
139
  - bin/setup
153
140
  - lib/acme-client.rb
@@ -194,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
181
  - !ruby/object:Gem::Version
195
182
  version: '0'
196
183
  requirements: []
197
- rubygems_version: 3.4.13
184
+ rubygems_version: 3.4.20
198
185
  signing_key:
199
186
  specification_version: 4
200
187
  summary: Client for the ACME protocol.