acme-cli 0.6.1 → 2.0.0

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
- 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