letscert 0.4.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9713b8f8c57715a49c9a47ee496be861b140605e
4
- data.tar.gz: b066af17d583c2a87e246729fe4ec52478b529b2
3
+ metadata.gz: 52add53a57fa00b0778f2a493f17f60c52c66420
4
+ data.tar.gz: 918a0428e5ec2c2c7f05c29eb41fcd60cd43a5f6
5
5
  SHA512:
6
- metadata.gz: cf1ee72bfb5f7e348ab4dbe35a674e2c723e8004f241a28a705787d9947ab1d1abe1fd0b8788d84f3b7c8734ccd34f6cc6b44b1513f1f5c239b788506a757410
7
- data.tar.gz: b2bf80554770b4545bf343b12676412b6074979dc92d6e9966ac7bdc9922bef503afa201dd538d20f187f7146f4388ff9ecadab073aec0019dcd824e4f6963bd
6
+ metadata.gz: 7a5017b39b842d751148c95666fc2372c4af7158c2dada7ad5b5d4dd6e53fe1d38582090827271611fc7ddb94c1e8c8473f0ed6837f855e3c66eedca38b544b4
7
+ data.tar.gz: 9c9462d83f3b2fecba4c0d3ef73760257d4814df0aeb8aafeb177f096e34fec2ed896f8cea923b37ed358592c1b345ca8de1cd03c93b6f43df0dc44647502987
checksums.yaml.gz.sig CHANGED
Binary file
data/.travis.yml CHANGED
@@ -2,7 +2,8 @@ language: ruby
2
2
  rvm:
3
3
  - 2.1
4
4
  - 2.2
5
- - 2.3.1
5
+ - 2.3.3
6
+ - 2.4.0
6
7
 
7
8
  install:
8
9
  - gem install bundler
data/letscert.gemspec CHANGED
@@ -23,10 +23,10 @@ EOF
23
23
 
24
24
  s.required_ruby_version = '>= 2.1.0'
25
25
 
26
- s.add_dependency 'acme-client', '~>0.5.0'
26
+ s.add_dependency 'acme-client', '~>0.5.5'
27
27
 
28
28
  s.add_development_dependency 'bundler', '~> 1.12'
29
- s.add_development_dependency 'rake', '~> 10.0'
29
+ s.add_development_dependency 'rake', '~> 11.0'
30
30
  s.add_development_dependency 'rspec', '~>3.4'
31
31
  s.add_development_dependency 'vcr', '~>3.0'
32
32
  s.add_development_dependency 'yard', '~>0.8'
@@ -21,6 +21,7 @@
21
21
  # SOFTWARE.
22
22
  require 'acme-client'
23
23
  require_relative 'loggable'
24
+ require_relative 'patched_ec_pkey'
24
25
 
25
26
  # rubocop:disable Metrics/ClassLength, Style/MultilineBlockLayout
26
27
  # rubocop:disable Style/BlockEndNewline, Style/BlockDelimiters
@@ -82,7 +83,7 @@ module LetsCert
82
83
  else
83
84
  logger.info { 'Generate new private key' }
84
85
  generate_certificate options[:roots].keys,
85
- options[:cert_key_size]
86
+ options
86
87
  end
87
88
 
88
89
  options[:files] ||= []
@@ -299,6 +300,52 @@ module LetsCert
299
300
  end
300
301
  end
301
302
 
303
+ # Generate a key from options
304
+ # @param [Hash] options +:cert_ecdsa+ and +:cert_rsa+ are mutually
305
+ # exclusive.
306
+ # @option options [Integer] :cert_ecdsa curve for which generate a cert
307
+ # @option options [Integer] :cert_rsa key size to generate a RSA key
308
+ # @return [OpenSSL::Pkey::PKey]
309
+ # @raise [Error]
310
+ def generate_key(options)
311
+ if options[:cert_ecdsa] and options[:cert_rsa]
312
+ raise Error, 'cannot generate a ECDSA key and a RSA key in one shot'
313
+ end
314
+
315
+ if options[:cert_ecdsa]
316
+ generate_ecdsa_key options[:cert_ecdsa]
317
+ else
318
+ OpenSSL::PKey::RSA.generate options[:cert_rsa]
319
+ end
320
+ end
321
+
322
+ # Generate a ECDSA key
323
+ # @param [String] curve curve name
324
+ # @return [OpenSSL::PKey::EC]
325
+ def generate_ecdsa_key(curve)
326
+ key = (PatchedECPkey.needed? ? PatchedECPkey : OpenSSL::PKey::EC).new
327
+ key.group = OpenSSL::PKey::EC::Group.new(curve)
328
+ key.generate_key
329
+ rescue OpenSSL::PKey::EC::Group::Error => ex
330
+ raise unless ex.message =~ /^unknown curve/
331
+ msg = "unknown curve. Supported curves are:\n"
332
+ msg << secure_curves.join("\n")
333
+ raise Error, msg
334
+ end
335
+
336
+ # Return array of secure curve names
337
+ # @return [Array<String>]
338
+ def secure_curves
339
+ curves = OpenSSL::PKey::EC.builtin_curves.map { |ary| '%-20s%s' % ary }
340
+ # Remove all binary curves, and prime curves which field is less than
341
+ # 256 bits
342
+ curves.reject! do |el|
343
+ el =~ /binary/ or (el =~ /(\d+) bit/ and $1.to_i < 256)
344
+ end
345
+
346
+ curves
347
+ end
348
+
302
349
  # Generate new certificate for given domains with existing private key
303
350
  # @param [Array<String>] domains
304
351
  # @param [OpenSSL::PKey::PKey] pkey private key to use
@@ -315,10 +362,11 @@ module LetsCert
315
362
 
316
363
  # Generate new certificate for given domains
317
364
  # @param [Array<String>] domains
318
- # @param [Integer] pkey_size size in bits for private key to generate
365
+ # @param [Hash] options option hash containing +:cert_ecdsa+, +:cert_rsa+
366
+ # or +:cert_key_size+ key.
319
367
  # @return [OpenSSL::PKey::PKey] generated private key
320
- def generate_certificate(domains, pkey_size)
321
- pkey = OpenSSL::PKey::RSA.generate(pkey_size)
368
+ def generate_certificate(domains, options)
369
+ pkey = generate_key(options)
322
370
  generate_certificate_from_pkey domains, pkey
323
371
  end
324
372
 
@@ -0,0 +1,16 @@
1
+ require 'openssl'
2
+
3
+ module LetsCert
4
+ # Ruby < 2.4 has bugs in OpenSSL. This class patches these bugs.
5
+ # @author Sylvain Daubert
6
+ class PatchedECPkey < OpenSSL::PKey::EC
7
+ alias :private? :private_key?
8
+ alias :public? :public_key?
9
+
10
+ # Say if {PatchedECPkey} is needed
11
+ # @return [Boolean]
12
+ def self.needed?
13
+ RbConfig::CONFIG['MAJOR'] == '2' && RbConfig::CONFIG['MINOR'].to_i < 4
14
+ end
15
+ end
16
+ end
@@ -42,6 +42,9 @@ module LetsCert
42
42
  # Exit value for error(s)
43
43
  RETURN_ERROR = 2
44
44
 
45
+ # Default key size for RSA certificates
46
+ RSA_DEFAULT_KEY_SIZE = 2048
47
+
45
48
  # Get options
46
49
  # @return [Hash]
47
50
  attr_reader :options
@@ -62,7 +65,6 @@ module LetsCert
62
65
  verbose: 0,
63
66
  domains: [],
64
67
  files: [],
65
- cert_key_size: 2048,
66
68
  valid_min: ValidTime.new('30d'),
67
69
  account_key_size: 4096,
68
70
  tos_sha256: '33d233c8ab558ba6c8ebc370a509acdded8b80e5d587aa5d192193f3' \
@@ -150,10 +152,21 @@ module LetsCert
150
152
  @options[:files] << file
151
153
  end
152
154
 
155
+ opts.on('--cert-ecdsa CURVE', String,
156
+ 'Generate ECDSA certificate on CURVE') do |curve|
157
+ @options[:cert_ecdsa] = curve
158
+ end
159
+
160
+ opts.on('--cert-rsa BITS', Integer,
161
+ 'Generate RSA certificate with a BITS-bit',
162
+ 'private key') do |bits|
163
+ @options[:cert_rsa] = bits
164
+ end
153
165
  opts.on('--cert-key-size BITS', Integer,
154
166
  'Certificate key size in bits',
155
- "(default: #{@options[:cert_key_size]})") do |bits|
156
- @options[:cert_key_size] = bits
167
+ '(equivalent to --cert-rsa)',
168
+ "(default: #{RSA_DEFAULT_KEY_SIZE})") do |bits|
169
+ @options[:cert_rsa] = bits
157
170
  end
158
171
 
159
172
  opts.accept(ValidTime) do |valid_time|
@@ -207,6 +220,7 @@ module LetsCert
207
220
 
208
221
  @opt_parser.parse!
209
222
  compute_roots
223
+ select_default_cert_type_if_none_specified
210
224
  end
211
225
 
212
226
  # Check all components are covered by plugins
@@ -354,6 +368,12 @@ module LetsCert
354
368
  @options[:roots] = roots
355
369
  end
356
370
 
371
+ def select_default_cert_type_if_none_specified
372
+ if @options[:cert_ecdsa].nil? and @options[:cert_rsa].nil?
373
+ @options[:cert_rsa] = RSA_DEFAULT_KEY_SIZE
374
+ end
375
+ end
376
+
357
377
  def persisted_data
358
378
  persisted = IOPlugin.empty_data
359
379
  @options[:files].each do |file|
@@ -1,6 +1,6 @@
1
1
  module LetsCert
2
2
 
3
3
  # Letscert version number
4
- VERSION = '0.4.5'.freeze
4
+ VERSION = '0.5.0'.freeze
5
5
 
6
6
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: letscert
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Daubert
@@ -31,7 +31,7 @@ cert_chain:
31
31
  dMi8WSKt03lfzyxIqZseBwVYYn+XMlzCcJLXCUgZXHcBRRRDH5wGDqOqXjL25b2O
32
32
  6m3JJngqkCFrOw==
33
33
  -----END CERTIFICATE-----
34
- date: 2016-11-21 00:00:00.000000000 Z
34
+ date: 2017-04-18 00:00:00.000000000 Z
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: acme-client
@@ -39,14 +39,14 @@ dependencies:
39
39
  requirements:
40
40
  - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: 0.5.0
42
+ version: 0.5.5
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: 0.5.0
49
+ version: 0.5.5
50
50
  - !ruby/object:Gem::Dependency
51
51
  name: bundler
52
52
  requirement: !ruby/object:Gem::Requirement
@@ -67,14 +67,14 @@ dependencies:
67
67
  requirements:
68
68
  - - "~>"
69
69
  - !ruby/object:Gem::Version
70
- version: '10.0'
70
+ version: '11.0'
71
71
  type: :development
72
72
  prerelease: false
73
73
  version_requirements: !ruby/object:Gem::Requirement
74
74
  requirements:
75
75
  - - "~>"
76
76
  - !ruby/object:Gem::Version
77
- version: '10.0'
77
+ version: '11.0'
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: rspec
80
80
  requirement: !ruby/object:Gem::Requirement
@@ -162,6 +162,7 @@ files:
162
162
  - lib/letscert/io_plugins/key_file.rb
163
163
  - lib/letscert/io_plugins/openssl_io_plugin.rb
164
164
  - lib/letscert/loggable.rb
165
+ - lib/letscert/patched_ec_pkey.rb
165
166
  - lib/letscert/runner.rb
166
167
  - lib/letscert/runner/logger_formatter.rb
167
168
  - lib/letscert/valid_time.rb
@@ -186,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
187
  version: '0'
187
188
  requirements: []
188
189
  rubyforge_project:
189
- rubygems_version: 2.5.1
190
+ rubygems_version: 2.5.2
190
191
  signing_key:
191
192
  specification_version: 4
192
193
  summary: letscert, a simple Let's Encrypt client
metadata.gz.sig CHANGED
Binary file