acme-cli 0.6.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2c369f88a826a9465922871deb4fbd8b3c232414
4
- data.tar.gz: c706f4fa29eed7d87f3a3e421e4bcd7cea0fa43c
2
+ SHA256:
3
+ metadata.gz: c426da565e907b19f9a87cd785aef871d1e9c43bc7ce91380376a459198abb49
4
+ data.tar.gz: fdecdc6b9a931dc8526fd52b53e7b7c5c2882af978ad6d44f5035877a0e38a4b
5
5
  SHA512:
6
- metadata.gz: bcd2a95fea94d400d9e118c8c68034e12ddf0dd9f6e768367c33f8e0d454ab2e187502191c593c820d558e34da91be8898ba5b4c03ec0e44b0d11b871eba3218
7
- data.tar.gz: c9dec9b4a406dc85135d1d746e0bffde678d3fdcfe4fc354496bc6203104ff0e459daa18b3703977405f2c7e70195ec0ca61ecee85c1aaa5ddc397466d5507df
6
+ metadata.gz: cf06389946f95ed0b16cfa74101ffee3012be8b0b20618e497bdeeac58998ff28295ab8b00cbefbe47d5fdd63e262f31b78ef495bc0befacfb8f3be408f13487
7
+ data.tar.gz: a9276b7d8b2aeed105601c626b5e1b5f7db00009f3a483a9f6e176d485f0053d41988b952666d0433e2875c03b05f6aa8d58112aee26221e7d225db240501827
data/acme-cli.gemspec CHANGED
@@ -10,16 +10,16 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["stwienert@gmail.com"]
11
11
 
12
12
  spec.summary = %q{slim ACME (e. g. letsencrypt) client for quickly authorizing (multiple) domains and issuing certificates}
13
- spec.homepage = "https://github.com/zealot28/acme-cli"
13
+ spec.homepage = "https://github.com/zealot28/ruby-acme-cli"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = '>= 2.0.0'
15
+ spec.required_ruby_version = '>= 2.1.0'
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
18
  spec.bindir = "exe"
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_runtime_dependency 'acme-client', '>= 0.2.4'
22
+ spec.add_runtime_dependency 'acme-client', '>= 2.0.0'
23
23
  spec.add_runtime_dependency 'thor'
24
24
  spec.add_runtime_dependency 'colorize'
25
25
 
@@ -2,6 +2,7 @@ require 'json'
2
2
  require 'acme-client'
3
3
  require 'logger'
4
4
  require 'colorize'
5
+ require_relative 'support/certificate'
5
6
 
6
7
  class AcmeWrapper
7
8
  def initialize(options)
@@ -22,28 +23,34 @@ class AcmeWrapper
22
23
  end
23
24
 
24
25
  def client
25
- @client ||= Acme::Client.new(private_key: account_key, endpoint: endpoint)
26
+ @client ||= Acme::Client.new(private_key: account_key, directory: directory)
26
27
  end
27
28
 
28
- def authorize(domain)
29
+ def create_order(domains)
30
+ log "Creating order for domains #{domains.to_s.blue}"
31
+ return client.new_order(identifiers: domains)
32
+ end
33
+
34
+ def authorize(authorization)
35
+ domain = authorization.domain
29
36
  FileUtils.mkdir_p(@options[:webroot_path])
30
37
  log "Authorizing #{domain.blue}.."
31
- authorization = client.authorize(domain: domain)
32
-
33
- challenge = authorization.http01
38
+ challenge = authorization.http
34
39
 
35
40
  challenge_file = File.join(@options[:webroot_path], challenge.filename.split('/').last)
36
41
  log "Writing challenge to #{challenge_file}", :debug
37
42
  File.write(challenge_file, challenge.file_content)
38
43
 
39
- challenge.request_verification
44
+ challenge.request_validation
40
45
 
41
- 5.times do
46
+ 10.times do
42
47
  log "Checking verification...", :debug
43
48
  sleep 1
44
- break if challenge.verify_status != 'pending'
49
+ challenge.reload
50
+ break if challenge.status != 'pending'
45
51
  end
46
- if challenge.verify_status == 'valid'
52
+
53
+ if challenge.status == 'valid'
47
54
  log "Authorization successful for #{domain.green}"
48
55
  File.unlink(challenge_file)
49
56
  true
@@ -84,7 +91,13 @@ class AcmeWrapper
84
91
  csr.version = 2
85
92
  csr.public_key = certificate_private_key.public_key
86
93
  csr.sign(certificate_private_key, OpenSSL::Digest::SHA256.new)
87
- certificate = client.new_certificate(csr)
94
+ order = create_order(domains)
95
+ order.finalize(csr: csr)
96
+ while order.status == 'processing'
97
+ sleep(1)
98
+ order.reload
99
+ end
100
+ certificate = Certificate.new(order.certificate)
88
101
  File.write(@options[:fullchain_path], certificate.fullchain_to_pem)
89
102
  File.write(@options[:chain_path], certificate.chain_to_pem)
90
103
  File.write(@options[:certificate_path], certificate.to_pem)
@@ -114,7 +127,7 @@ class AcmeWrapper
114
127
  return false
115
128
  end
116
129
  cert = OpenSSL::X509::Certificate.new(File.read(path))
117
- if client.revoke_certificate(cert)
130
+ if client.revoke(certificate: cert)
118
131
  log "Certificate '#{path}' was revoked", :info
119
132
  end
120
133
  true
@@ -147,14 +160,14 @@ class AcmeWrapper
147
160
  exit 2
148
161
  end
149
162
 
150
- false
163
+ false
151
164
  end
152
165
 
153
- def endpoint
166
+ def directory
154
167
  if @options[:test]
155
- "https://acme-staging.api.letsencrypt.org"
168
+ "https://acme-staging-v02.api.letsencrypt.org/directory"
156
169
  else
157
- "https://acme-v01.api.letsencrypt.org"
170
+ "https://acme-v02.api.letsencrypt.org/directory"
158
171
  end
159
172
  end
160
173
 
@@ -20,8 +20,7 @@ module Letsencrypt
20
20
  wrapper.log "not an email", :fatal
21
21
  exit 1
22
22
  end
23
- registration = wrapper.client.register(contact: "mailto:" + email)
24
- registration.agree_terms
23
+ registration = wrapper.client.new_account(contact: "mailto:" + email, terms_of_service_agreed: true)
25
24
  wrapper.log "Account created, Terms accepted"
26
25
  end
27
26
 
@@ -38,8 +37,9 @@ module Letsencrypt
38
37
  method_option :webroot_path, desc: "Path to mapped .well-known/acme-challenge folder (no subdirs will be created)", aliases: '-w', required: true
39
38
  def authorize(*domains)
40
39
  rc = 0
41
- domains.each do |domain|
42
- if !wrapper.authorize(domain)
40
+ order = wrapper.create_order(domains)
41
+ order.authorizations.each do |authorization|
42
+ if !wrapper.authorize(authorization)
43
43
  rc = 1
44
44
  end
45
45
  end
@@ -0,0 +1,29 @@
1
+ class Certificate
2
+ extend Forwardable
3
+
4
+ attr_reader :x509, :x509_chain
5
+
6
+ def_delegators :x509, :to_pem, :to_der
7
+
8
+ def initialize(fullchain_certificate)
9
+ fullchain_array = fullchain_certificate.strip.split("\n\n")
10
+ @x509 = OpenSSL::X509::Certificate.new(fullchain_array.first)
11
+ @x509_chain = fullchain_array[1..-1].map { |cert| OpenSSL::X509::Certificate.new(cert) }
12
+ end
13
+
14
+ def chain_to_pem
15
+ x509_chain.map(&:to_pem).join("\n")
16
+ end
17
+
18
+ def x509_fullchain
19
+ [x509, *x509_chain]
20
+ end
21
+
22
+ def fullchain_to_pem
23
+ x509_fullchain.map(&:to_pem).join("\n")
24
+ end
25
+
26
+ def common_name
27
+ x509.subject.to_a.find { |name, _, _| name == 'CN' }[1]
28
+ end
29
+ end
@@ -1,5 +1,5 @@
1
1
  module Letsencrypt
2
2
  module Cli
3
- VERSION = "0.6.1"
3
+ VERSION = "2.0.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acme-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Wienert
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-02-20 00:00:00.000000000 Z
11
+ date: 2021-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acme-client
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.4
19
+ version: 2.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.4
26
+ version: 2.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: thor
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -203,8 +203,9 @@ files:
203
203
  - lib/letsencrypt/cli.rb
204
204
  - lib/letsencrypt/cli/acme_wrapper.rb
205
205
  - lib/letsencrypt/cli/app.rb
206
+ - lib/letsencrypt/cli/support/certificate.rb
206
207
  - lib/letsencrypt/cli/version.rb
207
- homepage: https://github.com/zealot28/acme-cli
208
+ homepage: https://github.com/zealot28/ruby-acme-cli
208
209
  licenses:
209
210
  - MIT
210
211
  metadata: {}
@@ -216,7 +217,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
216
217
  requirements:
217
218
  - - ">="
218
219
  - !ruby/object:Gem::Version
219
- version: 2.0.0
220
+ version: 2.1.0
220
221
  required_rubygems_version: !ruby/object:Gem::Requirement
221
222
  requirements:
222
223
  - - ">="
@@ -224,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
224
225
  version: '0'
225
226
  requirements: []
226
227
  rubyforge_project:
227
- rubygems_version: 2.6.14
228
+ rubygems_version: 2.7.6
228
229
  signing_key:
229
230
  specification_version: 4
230
231
  summary: slim ACME (e. g. letsencrypt) client for quickly authorizing (multiple) domains