From cd809a6b69790b48344abfaa294edd8c4d4c7231 Mon Sep 17 00:00:00 2001 From: elijah Date: Tue, 30 Aug 2016 23:27:39 -0700 Subject: added acme-client gem --- .../lib/acme/client/resources/authorization.rb | 44 ++++++++++++++++++++++ .../lib/acme/client/resources/challenges.rb | 6 +++ .../lib/acme/client/resources/challenges/base.rb | 43 +++++++++++++++++++++ .../lib/acme/client/resources/challenges/dns01.rb | 19 ++++++++++ .../lib/acme/client/resources/challenges/http01.rb | 18 +++++++++ .../acme/client/resources/challenges/tls_sni01.rb | 24 ++++++++++++ .../lib/acme/client/resources/registration.rb | 37 ++++++++++++++++++ 7 files changed, 191 insertions(+) create mode 100644 vendor/acme-client/lib/acme/client/resources/authorization.rb create mode 100644 vendor/acme-client/lib/acme/client/resources/challenges.rb create mode 100644 vendor/acme-client/lib/acme/client/resources/challenges/base.rb create mode 100644 vendor/acme-client/lib/acme/client/resources/challenges/dns01.rb create mode 100644 vendor/acme-client/lib/acme/client/resources/challenges/http01.rb create mode 100644 vendor/acme-client/lib/acme/client/resources/challenges/tls_sni01.rb create mode 100644 vendor/acme-client/lib/acme/client/resources/registration.rb (limited to 'vendor/acme-client/lib/acme/client/resources') diff --git a/vendor/acme-client/lib/acme/client/resources/authorization.rb b/vendor/acme-client/lib/acme/client/resources/authorization.rb new file mode 100644 index 0000000..9ca2e76 --- /dev/null +++ b/vendor/acme-client/lib/acme/client/resources/authorization.rb @@ -0,0 +1,44 @@ +class Acme::Client::Resources::Authorization + HTTP01 = Acme::Client::Resources::Challenges::HTTP01 + DNS01 = Acme::Client::Resources::Challenges::DNS01 + TLSSNI01 = Acme::Client::Resources::Challenges::TLSSNI01 + + attr_reader :client, :uri, :domain, :status, :expires, :http01, :dns01, :tls_sni01 + + def initialize(client, uri, response) + @client = client + @uri = uri + assign_attributes(response.body) + end + + def verify_status + response = @client.connection.get(@uri) + + assign_attributes(response.body) + status + end + + private + + def assign_attributes(body) + @expires = Time.iso8601(body['expires']) if body.key? 'expires' + @domain = body['identifier']['value'] + @status = body['status'] + assign_challenges(body['challenges']) + end + + def assign_challenges(challenges) + challenges.each do |attributes| + challenge = case attributes.fetch('type') + when 'http-01' + @http01 ||= HTTP01.new(self) + when 'dns-01' + @dns01 ||= DNS01.new(self) + when 'tls-sni-01' + @tls_sni01 ||= TLSSNI01.new(self) + end + + challenge.assign_attributes(attributes) if challenge + end + end +end diff --git a/vendor/acme-client/lib/acme/client/resources/challenges.rb b/vendor/acme-client/lib/acme/client/resources/challenges.rb new file mode 100644 index 0000000..ec92d47 --- /dev/null +++ b/vendor/acme-client/lib/acme/client/resources/challenges.rb @@ -0,0 +1,6 @@ +module Acme::Client::Resources::Challenges; end + +require 'acme/client/resources/challenges/base' +require 'acme/client/resources/challenges/http01' +require 'acme/client/resources/challenges/dns01' +require 'acme/client/resources/challenges/tls_sni01' diff --git a/vendor/acme-client/lib/acme/client/resources/challenges/base.rb b/vendor/acme-client/lib/acme/client/resources/challenges/base.rb new file mode 100644 index 0000000..c78c74e --- /dev/null +++ b/vendor/acme-client/lib/acme/client/resources/challenges/base.rb @@ -0,0 +1,43 @@ +class Acme::Client::Resources::Challenges::Base + attr_reader :authorization, :status, :uri, :token, :error + + def initialize(authorization) + @authorization = authorization + end + + def client + authorization.client + end + + def verify_status + authorization.verify_status + + status + end + + def request_verification + response = client.connection.post(@uri, resource: 'challenge', type: challenge_type, keyAuthorization: authorization_key) + response.success? + end + + def assign_attributes(attributes) + @status = attributes.fetch('status', 'pending') + @uri = attributes.fetch('uri') + @token = attributes.fetch('token') + @error = attributes['error'] + end + + private + + def challenge_type + self.class::CHALLENGE_TYPE + end + + def authorization_key + "#{token}.#{crypto.thumbprint}" + end + + def crypto + @crypto ||= Acme::Client::Crypto.new(client.private_key) + end +end diff --git a/vendor/acme-client/lib/acme/client/resources/challenges/dns01.rb b/vendor/acme-client/lib/acme/client/resources/challenges/dns01.rb new file mode 100644 index 0000000..543f438 --- /dev/null +++ b/vendor/acme-client/lib/acme/client/resources/challenges/dns01.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class Acme::Client::Resources::Challenges::DNS01 < Acme::Client::Resources::Challenges::Base + CHALLENGE_TYPE = 'dns-01'.freeze + RECORD_NAME = '_acme-challenge'.freeze + RECORD_TYPE = 'TXT'.freeze + + def record_name + RECORD_NAME + end + + def record_type + RECORD_TYPE + end + + def record_content + crypto.urlsafe_base64(crypto.digest.digest(authorization_key)) + end +end diff --git a/vendor/acme-client/lib/acme/client/resources/challenges/http01.rb b/vendor/acme-client/lib/acme/client/resources/challenges/http01.rb new file mode 100644 index 0000000..4966091 --- /dev/null +++ b/vendor/acme-client/lib/acme/client/resources/challenges/http01.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class Acme::Client::Resources::Challenges::HTTP01 < Acme::Client::Resources::Challenges::Base + CHALLENGE_TYPE = 'http-01'.freeze + CONTENT_TYPE = 'text/plain'.freeze + + def content_type + CONTENT_TYPE + end + + def file_content + authorization_key + end + + def filename + ".well-known/acme-challenge/#{token}" + end +end diff --git a/vendor/acme-client/lib/acme/client/resources/challenges/tls_sni01.rb b/vendor/acme-client/lib/acme/client/resources/challenges/tls_sni01.rb new file mode 100644 index 0000000..8f455f5 --- /dev/null +++ b/vendor/acme-client/lib/acme/client/resources/challenges/tls_sni01.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class Acme::Client::Resources::Challenges::TLSSNI01 < Acme::Client::Resources::Challenges::Base + CHALLENGE_TYPE = 'tls-sni-01'.freeze + + def hostname + digest = crypto.digest.hexdigest(authorization_key) + "#{digest[0..31]}.#{digest[32..64]}.acme.invalid" + end + + def certificate + self_sign_certificate.certificate + end + + def private_key + self_sign_certificate.private_key + end + + private + + def self_sign_certificate + @self_sign_certificate ||= Acme::Client::SelfSignCertificate.new(subject_alt_names: [hostname]) + end +end diff --git a/vendor/acme-client/lib/acme/client/resources/registration.rb b/vendor/acme-client/lib/acme/client/resources/registration.rb new file mode 100644 index 0000000..b7a4c11 --- /dev/null +++ b/vendor/acme-client/lib/acme/client/resources/registration.rb @@ -0,0 +1,37 @@ +class Acme::Client::Resources::Registration + attr_reader :id, :key, :contact, :uri, :next_uri, :recover_uri, :term_of_service_uri + + def initialize(client, response) + @client = client + @uri = response.headers['location'] + assign_links(response.headers['Link']) + assign_attributes(response.body) + end + + def get_terms + return unless @term_of_service_uri + + @client.connection.get(@term_of_service_uri).body + end + + def agree_terms + return true unless @term_of_service_uri + + response = @client.connection.post(@uri, resource: 'reg', agreement: @term_of_service_uri) + response.success? + end + + private + + def assign_links(links) + @next_uri = links['next'] + @recover_uri = links['recover'] + @term_of_service_uri = links['terms-of-service'] + end + + def assign_attributes(body) + @id = body['id'] + @key = body['key'] + @contact = body['contact'] + end +end -- cgit v1.2.3