acme-client 0.2.2 → 0.2.3

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
2
  SHA1:
3
- metadata.gz: 66b791acbcafdeb9a0cc7b1fc56977ff235771db
4
- data.tar.gz: fcc5bdffc2e7278301de2ad97745a0dd1400915e
3
+ metadata.gz: 9f9c42703db71639a5e1f5f01ce79d793343bd13
4
+ data.tar.gz: a6e9dbb2adcd1246db1c67417b8b4ac3e54fbe2c
5
5
  SHA512:
6
- metadata.gz: 1dda0e5460db94b43231b033513b28c6a88b7af1be4c201bd360b5fda5dab159eb684305177636f6a3327a5ef6b54359045c1f12a87c62312a510dddae3b8345
7
- data.tar.gz: c5d7b4f69f4455c56fdeb9611b66757e981ebd870582fca017656a6f9635bfd223cc1c2231c67a159682f66e369dad18e3ed81e259c9d931d4f0f5b11a3972de
6
+ metadata.gz: 62053ee6b500dbf4d239919f7b6522f47459fa08f78e62395877cde46dccc35ba3de028bdb032e305dd890c90b86de5d2e4b6b2c34f48e517198eca0ac162081
7
+ data.tar.gz: fca377ddccf602238402cbe0d49febe228690dd68fc4922a135b515d6178c8e0843c08225bb371853723717ce6794b22ca3399c505f804f0cf74a9e16acf9117
data/Gemfile CHANGED
@@ -1,8 +1,7 @@
1
1
  source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in acme-client.gemspec
4
2
  gemspec
5
3
 
6
4
  group :development, :test do
7
5
  gem 'pry'
6
+ gem 'ruby-prof', require: false
8
7
  end
data/README.md CHANGED
@@ -18,7 +18,7 @@ private_key = OpenSSL::PKey::RSA.new(2048)
18
18
  endpoint = 'https://acme-v01.api.letsencrypt.org/'
19
19
 
20
20
  # Initialize the client
21
- require 'acme-client'
21
+ require 'acme/client'
22
22
  client = Acme::Client.new(private_key: private_key, endpoint: endpoint)
23
23
 
24
24
  # If the private key is not known to the server, we need to register it for the first time.
@@ -67,12 +67,12 @@ challenge.verify_status # => 'valid'
67
67
 
68
68
  # We're going to need a certificate signing request. If not explicitly
69
69
  # specified, the first name listed becomes the common name.
70
- csr = Acme::CertificateRequest.new(names: %w[example.org www.example.org])
70
+ csr = Acme::Client::CertificateRequest.new(names: %w[example.org www.example.org])
71
71
 
72
72
  # We can now request a certificate, you can pass anything that returns
73
73
  # a valid DER encoded CSR when calling to_der on it, for example a
74
74
  # OpenSSL::X509::Request too.
75
- certificate = client.new_certificate(csr) # => #<Acme::Certificate ....>
75
+ certificate = client.new_certificate(csr) # => #<Acme::Client::Certificate ....>
76
76
 
77
77
  # Save the certificate and key
78
78
  File.write("privkey.pem", certificate.request.private_key.to_pem)
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'acme/version'
4
+ require 'acme/client/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'acme-client'
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
16
  spec.require_paths = ['lib']
17
17
 
18
- spec.add_development_dependency 'bundler', '>= 1.6.9'
18
+ spec.add_development_dependency 'bundler', '~> 1.6', '>= 1.6.9'
19
19
  spec.add_development_dependency 'rake', '~> 10.0'
20
20
  spec.add_development_dependency 'rspec', '~> 3.3', '>= 3.3.0'
21
21
  spec.add_development_dependency 'vcr', '~> 2.9', '>= 2.9.3'
@@ -1,14 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "acme-client"
3
+ require 'bundler/setup'
4
+ require 'acme-client'
5
5
 
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start
6
+ require 'pry'
7
+ Pry.start
data/bin/setup CHANGED
@@ -3,5 +3,3 @@ set -euo pipefail
3
3
  IFS=$'\n\t'
4
4
 
5
5
  bundle install
6
-
7
- # Do any other automated setup that you need to do here
@@ -1,4 +1,4 @@
1
- module Acme; end
1
+ module Acme; class Client; end; end
2
2
 
3
3
  require 'faraday'
4
4
  require 'json'
@@ -7,10 +7,10 @@ require 'openssl'
7
7
  require 'digest'
8
8
  require 'forwardable'
9
9
 
10
- require 'acme/certificate'
11
- require 'acme/certificate_request'
12
- require 'acme/crypto'
10
+ require 'acme/client/certificate'
11
+ require 'acme/client/certificate_request'
12
+ require 'acme/client/crypto'
13
13
  require 'acme/client'
14
- require 'acme/resources'
15
- require 'acme/faraday_middleware'
16
- require 'acme/error'
14
+ require 'acme/client/resources'
15
+ require 'acme/client/faraday_middleware'
16
+ require 'acme/client/error'
@@ -1,3 +1,5 @@
1
+ require "acme-client"
2
+
1
3
  class Acme::Client
2
4
  DEFAULT_ENDPOINT = 'http://127.0.0.1:4000'
3
5
  DIRECTORY_DEFAULT = {
@@ -21,7 +23,7 @@ class Acme::Client
21
23
  }
22
24
 
23
25
  response = connection.post(@operation_endpoints.fetch('new-reg'), payload)
24
- ::Acme::Resources::Registration.new(self, response)
26
+ ::Acme::Client::Resources::Registration.new(self, response)
25
27
  end
26
28
 
27
29
  def authorize(domain:)
@@ -34,7 +36,7 @@ class Acme::Client
34
36
  }
35
37
 
36
38
  response = connection.post(@operation_endpoints.fetch('new-authz'), payload)
37
- ::Acme::Resources::Authorization.new(self, response)
39
+ ::Acme::Client::Resources::Authorization.new(self, response)
38
40
  end
39
41
 
40
42
  def new_certificate(csr)
@@ -44,9 +46,30 @@ class Acme::Client
44
46
  }
45
47
 
46
48
  response = connection.post(@operation_endpoints.fetch('new-cert'), payload)
47
- ::Acme::Certificate.new(OpenSSL::X509::Certificate.new(response.body), fetch_chain(response), csr)
49
+ ::Acme::Client::Certificate.new(OpenSSL::X509::Certificate.new(response.body), fetch_chain(response), csr)
50
+ end
51
+
52
+ def revoke_certificate(certificate)
53
+ payload = { resource: 'revoke-cert', certificate: Base64.urlsafe_encode64(certificate.to_der) }
54
+ endpoint = @operation_endpoints.fetch('revoke-cert')
55
+ response = connection.post(endpoint, payload)
56
+ response.success?
57
+ end
58
+
59
+ def self.revoke_certificate(certificate, *arguments)
60
+ client = new(*arguments)
61
+ client.revoke_certificate(certificate)
62
+ end
63
+
64
+ def connection
65
+ @connection ||= Faraday.new(@endpoint) do |configuration|
66
+ configuration.use Acme::Client::FaradayMiddleware, client: self
67
+ configuration.adapter Faraday.default_adapter
68
+ end
48
69
  end
49
70
 
71
+ private
72
+
50
73
  def fetch_chain(response, limit=10)
51
74
  if limit == 0 || response.headers["link"].nil? || response.headers["link"]["up"].nil?
52
75
  []
@@ -56,13 +79,6 @@ class Acme::Client
56
79
  end
57
80
  end
58
81
 
59
- def connection
60
- @connection ||= Faraday.new(@endpoint) do |configuration|
61
- configuration.use Acme::FaradayMiddleware, client: self
62
- configuration.adapter Faraday.default_adapter
63
- end
64
- end
65
-
66
82
  def load_directory!
67
83
  @operation_endpoints = if @directory_uri
68
84
  response = connection.get(@directory_uri)
@@ -1,4 +1,4 @@
1
- class Acme::Certificate
1
+ class Acme::Client::Certificate
2
2
  extend Forwardable
3
3
 
4
4
  attr_reader :x509, :x509_chain, :request
@@ -1,4 +1,4 @@
1
- class Acme::CertificateRequest
1
+ class Acme::Client::CertificateRequest
2
2
  extend Forwardable
3
3
 
4
4
  DEFAULT_KEY_LENGTH = 2048
@@ -21,7 +21,7 @@ class Acme::CertificateRequest
21
21
  "L" => OpenSSL::ASN1::UTF8STRING
22
22
  }.freeze
23
23
 
24
- attr_reader :csr, :private_key, :common_name, :names, :subject
24
+ attr_reader :private_key, :common_name, :names, :subject
25
25
 
26
26
  def_delegators :csr, :to_pem, :to_der
27
27
 
@@ -43,8 +43,10 @@ class Acme::CertificateRequest
43
43
 
44
44
  @subject[SUBJECT_KEYS[:common_name]] ||= @common_name
45
45
  validate_subject
46
+ end
46
47
 
47
- @csr = generate
48
+ def csr
49
+ @csr ||= generate
48
50
  end
49
51
 
50
52
  private
@@ -1,4 +1,4 @@
1
- class Acme::Crypto
1
+ class Acme::Client::Crypto
2
2
  attr_reader :private_key
3
3
 
4
4
  def initialize(private_key)
@@ -13,19 +13,21 @@ class Acme::Crypto
13
13
  jwt.to_json(syntax: :flattened)
14
14
  end
15
15
 
16
- def jwk
17
- @jwk ||= JSON::JWK.new(public_key)
18
- end
19
-
20
16
  def thumbprint
21
17
  jwk.thumbprint
22
18
  end
23
19
 
24
- def public_key
25
- @public_key ||= private_key.public_key
26
- end
27
-
28
20
  def digest
29
21
  OpenSSL::Digest::SHA256.new
30
22
  end
23
+
24
+ private
25
+
26
+ def jwk
27
+ @jwk ||= JSON::JWK.new(public_key)
28
+ end
29
+
30
+ def public_key
31
+ @public_key ||= private_key.public_key
32
+ end
31
33
  end
@@ -0,0 +1,12 @@
1
+ class Acme::Client::Error < StandardError
2
+ class NotFound < Acme::Client::Error; end
3
+ class BadCSR < Acme::Client::Error; end
4
+ class BadNonce < Acme::Client::Error; end
5
+ class Connection < Acme::Client::Error; end
6
+ class Dnssec < Acme::Client::Error; end
7
+ class Malformed < Acme::Client::Error; end
8
+ class ServerInternal < Acme::Client::Error; end
9
+ class Acme::Tls < Acme::Client::Error; end
10
+ class Unauthorized < Acme::Client::Error; end
11
+ class UnknownHost < Acme::Client::Error; end
12
+ end
@@ -1,4 +1,4 @@
1
- class Acme::FaradayMiddleware < Faraday::Middleware
1
+ class Acme::Client::FaradayMiddleware < Faraday::Middleware
2
2
  attr_reader :env, :response, :client
3
3
 
4
4
  def initialize(app, client:)
@@ -13,7 +13,7 @@ class Acme::FaradayMiddleware < Faraday::Middleware
13
13
  end
14
14
 
15
15
  def on_complete(env)
16
- raise Acme::Error::NotFound, env.url.to_s if env.status == 404
16
+ raise Acme::Client::Error::NotFound, env.url.to_s if env.status == 404
17
17
 
18
18
  nonces << env.response_headers['replay-nonce']
19
19
 
@@ -27,7 +27,7 @@ class Acme::FaradayMiddleware < Faraday::Middleware
27
27
  link_header = env.response_headers['Link']
28
28
  links = link_header.split(', ').map do |entry|
29
29
  link = entry.match(/<(.*?)>;/).captures.first
30
- name = entry.match(/rel="([\w_-]+)"/).captures.first
30
+ name = entry.match(/rel="([\w-]+)"/).captures.first
31
31
  [name, link]
32
32
  end
33
33
 
@@ -37,10 +37,10 @@ class Acme::FaradayMiddleware < Faraday::Middleware
37
37
  return if env.success?
38
38
 
39
39
  error_name = env.body['type'].gsub('urn:acme:error:', '').classify
40
- error_class = if Acme::Error.qualified_const_defined?(error_name)
41
- "Acme::Error::#{error_name}".constantize
40
+ error_class = if Acme::Client::Error.qualified_const_defined?(error_name)
41
+ "Acme::Client::Error::#{error_name}".constantize
42
42
  else
43
- Acme::Error
43
+ Acme::Client::Error
44
44
  end
45
45
 
46
46
  message = if env.body.is_a? Hash
@@ -49,7 +49,7 @@ class Acme::FaradayMiddleware < Faraday::Middleware
49
49
  "Error message: #{env.body}"
50
50
  end
51
51
 
52
- raise error_class, env.body['detail']
52
+ raise error_class, message
53
53
  end
54
54
 
55
55
  private
@@ -76,6 +76,6 @@ class Acme::FaradayMiddleware < Faraday::Middleware
76
76
  end
77
77
 
78
78
  def crypto
79
- @crypto ||= Acme::Crypto.new(private_key)
79
+ @crypto ||= Acme::Client::Crypto.new(private_key)
80
80
  end
81
81
  end
@@ -0,0 +1,5 @@
1
+ module Acme::Client::Resources; end
2
+
3
+ require 'acme/client/resources/registration'
4
+ require 'acme/client/resources/challenges'
5
+ require 'acme/client/resources/authorization'
@@ -1,6 +1,6 @@
1
- class Acme::Resources::Authorization
2
- HTTP01 = Acme::Resources::Challenges::HTTP01
3
- DNS01 = Acme::Resources::Challenges::DNS01
1
+ class Acme::Client::Resources::Authorization
2
+ HTTP01 = Acme::Client::Resources::Challenges::HTTP01
3
+ DNS01 = Acme::Client::Resources::Challenges::DNS01
4
4
 
5
5
  attr_reader :domain, :status, :http01, :dns01
6
6
 
@@ -0,0 +1,5 @@
1
+ module Acme::Client::Resources::Challenges; end
2
+
3
+ require 'acme/client/resources/challenges/base'
4
+ require 'acme/client/resources/challenges/http01'
5
+ require 'acme/client/resources/challenges/dns01'
@@ -1,4 +1,4 @@
1
- class Acme::Resources::Challenges::Base
1
+ class Acme::Client::Resources::Challenges::Base
2
2
 
3
3
  attr_reader :client, :status, :uri, :token, :error
4
4
 
@@ -28,6 +28,6 @@ class Acme::Resources::Challenges::Base
28
28
  end
29
29
 
30
30
  def crypto
31
- @crypto ||= Acme::Crypto.new(@client.private_key)
31
+ @crypto ||= Acme::Client::Crypto.new(@client.private_key)
32
32
  end
33
33
  end
@@ -1,6 +1,6 @@
1
- class Acme::Resources::Challenges::DNS01 < Acme::Resources::Challenges::Base
2
- RECORD_NAME = '_acme-challenge'
3
- RECORD_TYPE = 'TXT'
1
+ class Acme::Client::Resources::Challenges::DNS01 < Acme::Client::Resources::Challenges::Base
2
+ RECORD_NAME = '_acme-challenge'.freeze
3
+ RECORD_TYPE = 'TXT'.freeze
4
4
 
5
5
  def record_name
6
6
  RECORD_NAME
@@ -1,5 +1,5 @@
1
- class Acme::Resources::Challenges::HTTP01 < Acme::Resources::Challenges::Base
2
- CONTENT_TYPE = 'text/plain'
1
+ class Acme::Client::Resources::Challenges::HTTP01 < Acme::Client::Resources::Challenges::Base
2
+ CONTENT_TYPE = 'text/plain'.freeze
3
3
 
4
4
  def content_type
5
5
  CONTENT_TYPE
@@ -1,4 +1,4 @@
1
- class Acme::Resources::Registration
1
+ class Acme::Client::Resources::Registration
2
2
  attr_reader :id, :key, :contact, :uri, :next_uri, :recover_uri, :term_of_service_uri
3
3
 
4
4
  def initialize(client, response)
@@ -1,5 +1,5 @@
1
1
  module Acme
2
2
  class Client
3
- VERSION = '0.2.2'
3
+ VERSION = '0.2.3'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,19 +1,22 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acme-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Barbier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-07 00:00:00.000000000 Z
11
+ date: 2015-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
17
20
  - - ">="
18
21
  - !ruby/object:Gem::Version
19
22
  version: 1.6.9
@@ -21,6 +24,9 @@ dependencies:
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.6'
24
30
  - - ">="
25
31
  - !ruby/object:Gem::Version
26
32
  version: 1.6.9
@@ -156,20 +162,20 @@ files:
156
162
  - bin/console
157
163
  - bin/setup
158
164
  - lib/acme-client.rb
159
- - lib/acme/certificate.rb
160
- - lib/acme/certificate_request.rb
161
165
  - lib/acme/client.rb
162
- - lib/acme/crypto.rb
163
- - lib/acme/error.rb
164
- - lib/acme/faraday_middleware.rb
165
- - lib/acme/resources.rb
166
- - lib/acme/resources/authorization.rb
167
- - lib/acme/resources/challenges.rb
168
- - lib/acme/resources/challenges/base.rb
169
- - lib/acme/resources/challenges/dns01.rb
170
- - lib/acme/resources/challenges/http01.rb
171
- - lib/acme/resources/registration.rb
172
- - lib/acme/version.rb
166
+ - lib/acme/client/certificate.rb
167
+ - lib/acme/client/certificate_request.rb
168
+ - lib/acme/client/crypto.rb
169
+ - lib/acme/client/error.rb
170
+ - lib/acme/client/faraday_middleware.rb
171
+ - lib/acme/client/resources.rb
172
+ - lib/acme/client/resources/authorization.rb
173
+ - lib/acme/client/resources/challenges.rb
174
+ - lib/acme/client/resources/challenges/base.rb
175
+ - lib/acme/client/resources/challenges/dns01.rb
176
+ - lib/acme/client/resources/challenges/http01.rb
177
+ - lib/acme/client/resources/registration.rb
178
+ - lib/acme/client/version.rb
173
179
  homepage: http://github.com/unixcharles/acme-client
174
180
  licenses:
175
181
  - MIT
@@ -1,12 +0,0 @@
1
- class Acme::Error < StandardError
2
- class NotFound < Acme::Error; end
3
- class BadCSR < Acme::Error; end
4
- class BadNonce < Acme::Error; end
5
- class Connection < Acme::Error; end
6
- class Dnssec < Acme::Error; end
7
- class Malformed < Acme::Error; end
8
- class ServerInternal < Acme::Error; end
9
- class Acme::Tls < Acme::Error; end
10
- class Unauthorized < Acme::Error; end
11
- class UnknownHost < Acme::Error; end
12
- end
@@ -1,4 +0,0 @@
1
- module Acme::Resources; end
2
- require 'acme/resources/registration'
3
- require 'acme/resources/challenges'
4
- require 'acme/resources/authorization'
@@ -1,4 +0,0 @@
1
- module Acme::Resources::Challenges; end
2
- require 'acme/resources/challenges/base'
3
- require 'acme/resources/challenges/http01'
4
- require 'acme/resources/challenges/dns01'