Commit 69597bf7 authored by Patrick J Cherry's avatar Patrick J Cherry
Browse files

common: LetsEncrypt registration for a key now tested with an auth request

There is no way to determine if an key is already registered with the
server.  Previously we just registered and caught any errors, but it
turns out that the Acme servers always return "Malformed" if there is
any problem with the request at all (e.g. bad email address, key
previously registered).  This means we can return a sane error to the
user if the request fails, without parsing the error text.

However if a key is not registered, the server will return Unauthorized
when requesting a new challenge via new-authz, so we can use that to see
if a key is valid or not.
parent d6c8de2d
......@@ -144,9 +144,15 @@ domains.each do |domain|
puts "\tFetching a new certificate from #{domain.ssl_provider}." if $VERBOSE
cert_set = domain.ssl_fetch_new_certificate
cert_set.name = domain.ssl_next_set
cert_set.write
begin
cert_set = domain.ssl_fetch_new_certificate
cert_set.name = domain.ssl_next_set
cert_set.write
rescue StandardError => err
puts "\t!! Failed: #{err.to_s.gsub($/,'')}" if $VERBOSE
puts err.backtrace.join("\n") if $DEBUG
end
end
......
......@@ -101,13 +101,19 @@ module Symbiosis
#
registration.agree_terms
return true
rescue Acme::Error::Malformed => err
warn "\t#{err.to_s} (when registering)" if $VERBOSE
return true
end
alias :registered? :register
#
# Tests to see if we're registered by doing a pre-emptive authorize
# request.
#
def registered?
self.client.authorize(domain: name)
return true
rescue Acme::Error::Unauthorized
return false
end
#
# This does the authorization. Returns true if the verification succeeds.
......
......@@ -78,6 +78,30 @@ class SSLLetsEncryptTest < Test::Unit::TestCase
{:status => 405, :headers => {"Replay-Nonce" => Symbiosis::Utils.random_string(20)}}
end
def do_check_key(request)
protect = JSON.load(UrlSafeBase64.decode64(request["protected"]))
key = nil
if protect.is_a?(Hash) and
protect.has_key?("jwk") and
protect["jwk"].is_a?(Hash) and
protect["jwk"].has_key?("n")
key = protect["jwk"]["n"]
end
if @registered_keys.include?(key)
true
else
{:status => 409,
:headers => {
"Location" => "#{@endpoint}/acme/reg/asdf",
"Content-Type"=>"application/problem+json",
},
:body => "{\"type\":\"urn:acme:error:unauthorized\",\"detail\":\"No registration exists matching provided key\",\"status\":409}",
}
end
end
def do_post_new_reg(request)
req = JSON.load(request.body)
protect = JSON.load(UrlSafeBase64.decode64(req["protected"]))
......@@ -110,6 +134,10 @@ class SSLLetsEncryptTest < Test::Unit::TestCase
def do_post_new_authz(request)
req = JSON.load(request.body)
result = do_check_key(req)
return result unless result == true
payload = JSON.load(UrlSafeBase64.decode64(req["payload"]))
sekrit = Symbiosis::Utils.random_string(20).downcase
......@@ -131,6 +159,10 @@ class SSLLetsEncryptTest < Test::Unit::TestCase
def do_post_authz(request)
req = JSON.load(request.body)
result = do_check_key(req)
return result unless result == true
payload = JSON.load(UrlSafeBase64.decode64(req["payload"]))
sekrit = @authz_template.extract(request.uri)["sekrit"]
......@@ -154,6 +186,10 @@ class SSLLetsEncryptTest < Test::Unit::TestCase
def do_post_new_cert(request)
req = JSON.load(request.body)
result = do_check_key(req)
return result unless result == true
payload = JSON.load(UrlSafeBase64.decode64(req["payload"]))
csr = OpenSSL::X509::Request.new(UrlSafeBase64.decode64(payload["csr"]))
......@@ -208,12 +244,17 @@ class SSLLetsEncryptTest < Test::Unit::TestCase
def test_register
omit unless @client
result = nil
result = @client.registered?
assert(!result, "#registered? should return false if we're not registered yet")
result = @client.register
assert(result, "#register should return true")
result = @client.register
assert(result, "#register should return true, even on the second attempt")
result = @client.registered?
assert(result, "#registered? should return true once registered")
assert_raise(Acme::Error::Malformed, "#register should return raise an error on second attempt") { @client.register }
end
def test_verify
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment