1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
require 'openssl'
require 'acme-client'
#
# A little bit of sugar around gem acme-client
#
module LeapCli
class Acme
if ENV['ACME_STAGING']
ENDPOINT = 'https://acme-staging.api.letsencrypt.org/'
puts "using endpoint " + ENDPOINT
else
ENDPOINT = 'https://acme-v01.api.letsencrypt.org/'
end
def initialize(domain: nil, key:)
@client = ::Acme::Client.new(
private_key: key,
endpoint: ENDPOINT,
connection_options: {request: {open_timeout: 5, timeout: 5}}
)
@domain = domain
end
#
# static methods
#
def self.new_private_key
return OpenSSL::PKey::RSA.new(4096)
end
def self.load_private_key(pem_encoded_key)
return OpenSSL::PKey::RSA.new(pem_encoded_key)
end
def self.load_csr(pem_encoded_csr)
return OpenSSL::X509::Request.new(pem_encoded_csr)
end
#
# instance methods
#
#
# register a new account key with CA
#
def register(contact)
registration = @client.register(contact: 'mailto:' + contact)
if registration && registration.agree_terms
return registration
else
return false
end
end
#
# authorize account key for domain
#
def authorize
authorization = @client.authorize(domain: @domain)
challenge = nil
begin
while true
if authorization.status == 'pending'
challenge = authorization.http01
yield challenge
challenge.request_verification
sleep 1
authorization.verify_status
if challenge.error
return 'error', challenge.error
end
elsif authorization.status == 'invalid'
challenge_msg = (challenge.nil? ? '' : challenge.error)
return 'error', 'Something bad happened. %s' % challenge_msg
elsif authorization.status == 'valid'
return 'valid', nil
else
challenge_msg = (challenge.nil? ? '' : challenge.error)
return 'error', 'status: %s, response message: %s' % [authorization.status, challenge_msg]
end
end
rescue Interrupt
return 'error', 'interrupted'
end
rescue ::Acme::Client::Error::Unauthorized => exc
return 'unauthorized', exc.to_s
end
#
# get new certificate
#
def get_certificate(csr)
return @client.new_certificate(csr)
end
end
end
|