acme-client 0.3.7 → 0.4.0
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 +4 -4
- data/acme-client.gemspec +0 -1
- data/lib/acme/client.rb +3 -1
- data/lib/acme/client/crypto.rb +72 -7
- data/lib/acme/client/faraday_middleware.rb +5 -3
- data/lib/acme/client/resources/challenges/dns01.rb +3 -1
- data/lib/acme/client/resources/challenges/http01.rb +2 -0
- data/lib/acme/client/resources/challenges/tls_sni01.rb +2 -0
- data/lib/acme/client/version.rb +3 -1
- metadata +2 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23f849edb70a3c4e33466410c19df3293242ec75
|
4
|
+
data.tar.gz: c610d9cabc6d2520b51654f3f140d2d12b8ecabe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4002d98a374002c504d3a6fdf4566b69dcb6eaf7bb298a111562a8911a2ccf3f10ba510795efbf41b03cf51b0a88c51fb900c30b22b914c66fe3c84ef729aff7
|
7
|
+
data.tar.gz: 7495152d76edaa3c3248518a14af07b103e8b4d3b5e22ca83ba1ca71aa93c7f6617a7c6925457e0994b1b10ca6c4807bfe3b5253c868bb512a317ab1b19a4e9b
|
data/acme-client.gemspec
CHANGED
data/lib/acme/client.rb
CHANGED
data/lib/acme/client/crypto.rb
CHANGED
@@ -6,26 +6,91 @@ class Acme::Client::Crypto
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def generate_signed_jws(header:, payload:)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
header = { typ: 'JWT', alg: jws_alg, jwk: jwk }.merge(header)
|
10
|
+
|
11
|
+
encoded_header = urlsafe_base64(header.to_json)
|
12
|
+
encoded_payload = urlsafe_base64(payload.to_json)
|
13
|
+
signature_data = "#{encoded_header}.#{encoded_payload}"
|
14
|
+
|
15
|
+
signature = private_key.sign digest, signature_data
|
16
|
+
encoded_signature = urlsafe_base64(signature)
|
17
|
+
|
18
|
+
{
|
19
|
+
protected: encoded_header,
|
20
|
+
payload: encoded_payload,
|
21
|
+
signature: encoded_signature
|
22
|
+
}.to_json
|
14
23
|
end
|
15
24
|
|
16
25
|
def thumbprint
|
17
|
-
jwk.
|
26
|
+
urlsafe_base64 digest.digest(jwk.to_json)
|
18
27
|
end
|
19
28
|
|
20
29
|
def digest
|
21
30
|
OpenSSL::Digest::SHA256.new
|
22
31
|
end
|
23
32
|
|
33
|
+
def urlsafe_base64(data)
|
34
|
+
Base64.urlsafe_encode64(data).sub(/[\s=]*\z/, '')
|
35
|
+
end
|
36
|
+
|
24
37
|
private
|
25
38
|
|
39
|
+
def jws_alg
|
40
|
+
{ 'RSA' => 'RS256', 'EC' => 'ES256' }.fetch(jwk[:kty])
|
41
|
+
end
|
42
|
+
|
26
43
|
def jwk
|
27
|
-
@jwk ||=
|
44
|
+
@jwk ||= case private_key
|
45
|
+
when OpenSSL::PKey::RSA
|
46
|
+
rsa_jwk
|
47
|
+
when OpenSSL::PKey::EC
|
48
|
+
ec_jwk
|
49
|
+
else
|
50
|
+
raise ArgumentError, "Can't handle #{private_key} as private key, only OpenSSL::PKey::RSA and OpenSSL::PKey::EC"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def rsa_jwk
|
55
|
+
{
|
56
|
+
e: urlsafe_base64(public_key.e.to_s(2)),
|
57
|
+
kty: 'RSA',
|
58
|
+
n: urlsafe_base64(public_key.n.to_s(2))
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
def ec_jwk
|
63
|
+
{
|
64
|
+
crv: curve_name,
|
65
|
+
kty: 'EC',
|
66
|
+
x: urlsafe_base64(coordinates[:x].to_s(2)),
|
67
|
+
y: urlsafe_base64(coordinates[:y].to_s(2))
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def curve_name
|
72
|
+
{
|
73
|
+
'prime256v1' => 'P-256',
|
74
|
+
'secp384r1' => 'P-384',
|
75
|
+
'secp521r1' => 'P-521'
|
76
|
+
}.fetch(private_key.group.curve_name) { raise ArgumentError, 'Unknown EC curve' }
|
77
|
+
end
|
78
|
+
|
79
|
+
# rubocop:disable Metrics/AbcSize
|
80
|
+
def coordinates
|
81
|
+
@coordinates ||= begin
|
82
|
+
hex = public_key.to_bn.to_s(16)
|
83
|
+
data_len = hex.length - 2
|
84
|
+
hex_x = hex[2, data_len / 2]
|
85
|
+
hex_y = hex[2 + data_len / 2, data_len / 2]
|
86
|
+
|
87
|
+
{
|
88
|
+
x: OpenSSL::BN.new([hex_x].pack('H*'), 2),
|
89
|
+
y: OpenSSL::BN.new([hex_y].pack('H*'), 2)
|
90
|
+
}
|
91
|
+
end
|
28
92
|
end
|
93
|
+
# rubocop:enable Metrics/AbcSize
|
29
94
|
|
30
95
|
def public_key
|
31
96
|
@public_key ||= private_key.public_key
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Acme::Client::FaradayMiddleware < Faraday::Middleware
|
2
4
|
attr_reader :env, :response, :client
|
3
5
|
|
@@ -50,8 +52,8 @@ class Acme::Client::FaradayMiddleware < Faraday::Middleware
|
|
50
52
|
end
|
51
53
|
|
52
54
|
def error_class
|
53
|
-
if error_name.
|
54
|
-
"Acme::Client::Error::#{error_name}"
|
55
|
+
if error_name && !error_name.empty? && Acme::Client::Error.const_defined?(error_name)
|
56
|
+
Object.const_get("Acme::Client::Error::#{error_name}")
|
55
57
|
else
|
56
58
|
Acme::Client::Error
|
57
59
|
end
|
@@ -62,7 +64,7 @@ class Acme::Client::FaradayMiddleware < Faraday::Middleware
|
|
62
64
|
return unless env.body.is_a?(Hash)
|
63
65
|
return unless env.body.key?('type')
|
64
66
|
|
65
|
-
env.body['type'].gsub('urn:acme:error:', '').
|
67
|
+
env.body['type'].gsub('urn:acme:error:', '').split(/[_-]/).map(&:capitalize).join
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Acme::Client::Resources::Challenges::DNS01 < Acme::Client::Resources::Challenges::Base
|
2
4
|
CHALLENGE_TYPE = 'dns-01'.freeze
|
3
5
|
RECORD_NAME = '_acme-challenge'.freeze
|
@@ -12,6 +14,6 @@ class Acme::Client::Resources::Challenges::DNS01 < Acme::Client::Resources::Chal
|
|
12
14
|
end
|
13
15
|
|
14
16
|
def record_content
|
15
|
-
|
17
|
+
crypto.urlsafe_base64(crypto.digest.digest(authorization_key))
|
16
18
|
end
|
17
19
|
end
|
data/lib/acme/client/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acme-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charles Barbier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -124,26 +124,6 @@ dependencies:
|
|
124
124
|
- - ">="
|
125
125
|
- !ruby/object:Gem::Version
|
126
126
|
version: 0.9.1
|
127
|
-
- !ruby/object:Gem::Dependency
|
128
|
-
name: json-jwt
|
129
|
-
requirement: !ruby/object:Gem::Requirement
|
130
|
-
requirements:
|
131
|
-
- - "~>"
|
132
|
-
- !ruby/object:Gem::Version
|
133
|
-
version: '1.2'
|
134
|
-
- - ">="
|
135
|
-
- !ruby/object:Gem::Version
|
136
|
-
version: 1.2.3
|
137
|
-
type: :runtime
|
138
|
-
prerelease: false
|
139
|
-
version_requirements: !ruby/object:Gem::Requirement
|
140
|
-
requirements:
|
141
|
-
- - "~>"
|
142
|
-
- !ruby/object:Gem::Version
|
143
|
-
version: '1.2'
|
144
|
-
- - ">="
|
145
|
-
- !ruby/object:Gem::Version
|
146
|
-
version: 1.2.3
|
147
127
|
description:
|
148
128
|
email:
|
149
129
|
- unixcharles@gmail.com
|