varanus 0.2.1 → 0.5.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21d141fb4a79d1be189992feb7ef7aec763e488024e516736dc2e9e9398bbb57
4
- data.tar.gz: 2eee7f27b14b98d0d1fcd061b16943be273c0f219a54440fbbab8fca601aebb7
3
+ metadata.gz: 67c52ba9ede6f495a05841bacfbf3046cb41b45cd8bb1d4ef8a1c7491e735644
4
+ data.tar.gz: 921e5bd93bf8caa0378ba15f45276b8100c19239d28e3e22b68e3ae76fa85da1
5
5
  SHA512:
6
- metadata.gz: 376cb245e647b3efc042495142c80c72e90d2fe4155d214560ca6788d3d2e0a619c4a91d37e304cf79d914e24bf79117256243f9023a206d4b93ff9439700248
7
- data.tar.gz: b83f3beb482ab7660d9fa0ffb4a8ee0593113823746f07a7aeb617c8900cbb27a773d9a7109917efc852d2de92a8f898f3a80d8af740ee29cc84c4b217b564da
6
+ metadata.gz: c2cf7fd0e7ec49ec4b9f6bdef82aae9f7cf8d05f0343cce7d8595dfd6a975cf0fc983045997ec0f6cbc8425b8935ff66bc3a7846cd321a55789508cb4ee03fce
7
+ data.tar.gz: c02ba0dfc6a9132204d50f3bc1453b878c73f34ca981ead6ffd29c35bc91fe637922085ac28ceb831fa0b22fe5fe1a3b61679314b99255e00774346689dc31d8
@@ -1,9 +1,15 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.3
2
+ NewCops: disable
3
+ TargetRubyVersion: 2.5
3
4
 
4
5
  Bundler/OrderedGems:
5
6
  AutoCorrect: false
6
7
 
8
+ Layout/LineLength:
9
+ Max: 90
10
+ Exclude:
11
+ - 'test/**/*'
12
+
7
13
  Metrics/AbcSize:
8
14
  Max: 25
9
15
  Exclude:
@@ -14,11 +20,6 @@ Metrics/ClassLength:
14
20
  Exclude:
15
21
  - 'test/**/*'
16
22
 
17
- Metrics/LineLength:
18
- Max: 90
19
- Exclude:
20
- - 'test/**/*'
21
-
22
23
  Metrics/MethodLength:
23
24
  Max: 20
24
25
  Exclude:
@@ -6,10 +6,9 @@ sudo: false
6
6
  language: ruby
7
7
  cache: bundler
8
8
  rvm:
9
- - 2.3
10
- - 2.4
11
9
  - 2.5
12
10
  - 2.6
11
+ - 2.7
13
12
  before_install: gem install bundler -v 1.16.5
14
13
  before_script:
15
14
  - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
@@ -1,4 +1,21 @@
1
- ### 0.2.1 (2018-22-13)
1
+ ### Version 0.5.1 (2021-01-28)
2
+ * Varanus::SSL::CSR - support EC certs
3
+
4
+ ### Version 0.5.0 (2021-01-26)
5
+ * Add Varanus::Domain
6
+ * Add Varanus::SSL#list and Varanus::SSL#info
7
+ * Add Varanus::Organization
8
+
9
+ ### 0.4.0 (2021-01-06)
10
+ * Add Varanus::DCV
11
+
12
+ ### 0.3.1 (2020-10-14)
13
+ * Fix issue when Sectigo reports two identical 'Short Life' certs
14
+
15
+ ### 0.3.0 (2020-08-24)
16
+ * Add support for new 'Short Life' certs
17
+
18
+ ### 0.2.1 (2018-11-13)
2
19
  * Increase timeout value for SSL requests
3
20
 
4
21
  ### 0.2.0 (2018-11-09)
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- varanus (0.2.0)
4
+ varanus (0.5.1)
5
5
  faraday
6
6
  faraday_middleware
7
7
  savon (~> 2.0)
@@ -9,58 +9,61 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- addressable (2.5.2)
13
- public_suffix (>= 2.0.2, < 4.0)
12
+ addressable (2.7.0)
13
+ public_suffix (>= 2.0.2, < 5.0)
14
14
  akami (1.3.1)
15
15
  gyoku (>= 0.4.0)
16
16
  nokogiri
17
- ast (2.4.0)
18
- builder (3.2.3)
19
- crack (0.4.3)
20
- safe_yaml (~> 1.0.0)
21
- docile (1.3.1)
22
- faraday (0.15.3)
17
+ ast (2.4.1)
18
+ builder (3.2.4)
19
+ crack (0.4.5)
20
+ rexml
21
+ docile (1.3.4)
22
+ faraday (1.3.0)
23
+ faraday-net_http (~> 1.0)
23
24
  multipart-post (>= 1.2, < 3)
24
- faraday_middleware (0.12.2)
25
- faraday (>= 0.7.4, < 1.0)
25
+ ruby2_keywords
26
+ faraday-net_http (1.0.0)
27
+ faraday_middleware (1.0.0)
28
+ faraday (~> 1.0)
26
29
  gyoku (1.3.1)
27
30
  builder (>= 2.1.2)
28
- hashdiff (0.3.7)
29
- httpi (2.4.4)
31
+ hashdiff (1.0.1)
32
+ httpi (2.4.5)
30
33
  rack
31
34
  socksify
32
- jaro_winkler (1.5.1)
33
- json (2.1.0)
34
- metaclass (0.0.4)
35
- mini_portile2 (2.3.0)
36
- minitest (5.11.3)
35
+ minitest (5.14.3)
37
36
  minitest-rg (5.2.0)
38
37
  minitest (~> 5.0)
39
- mocha (1.7.0)
40
- metaclass (~> 0.0.1)
41
- multipart-post (2.0.0)
42
- nokogiri (1.8.5)
43
- mini_portile2 (~> 2.3.0)
38
+ mocha (1.12.0)
39
+ multipart-post (2.1.1)
40
+ nokogiri (1.11.1-x86_64-linux)
41
+ racc (~> 1.4)
44
42
  nori (2.6.0)
45
- parallel (1.12.1)
46
- parser (2.5.3.0)
47
- ast (~> 2.4.0)
48
- powerpack (0.1.2)
49
- public_suffix (3.0.3)
50
- rack (2.0.6)
43
+ parallel (1.20.1)
44
+ parser (3.0.0.0)
45
+ ast (~> 2.4.1)
46
+ public_suffix (4.0.6)
47
+ racc (1.5.2)
48
+ rack (2.2.3)
51
49
  rainbow (3.0.0)
52
50
  rake (10.5.0)
53
- rubocop (0.60.0)
54
- jaro_winkler (~> 1.5.1)
51
+ regexp_parser (2.0.3)
52
+ rexml (3.2.4)
53
+ rubocop (1.7.0)
55
54
  parallel (~> 1.10)
56
- parser (>= 2.5, != 2.5.1.1)
57
- powerpack (~> 0.1)
55
+ parser (>= 2.7.1.5)
58
56
  rainbow (>= 2.2.2, < 4.0)
57
+ regexp_parser (>= 1.8, < 3.0)
58
+ rexml
59
+ rubocop-ast (>= 1.2.0, < 2.0)
59
60
  ruby-progressbar (~> 1.7)
60
- unicode-display_width (~> 1.4.0)
61
- ruby-progressbar (1.10.0)
62
- safe_yaml (1.0.4)
63
- savon (2.12.0)
61
+ unicode-display_width (>= 1.4.0, < 2.0)
62
+ rubocop-ast (1.4.0)
63
+ parser (>= 2.7.1.5)
64
+ ruby-progressbar (1.11.0)
65
+ ruby2_keywords (0.0.2)
66
+ savon (2.12.1)
64
67
  akami (~> 1.2)
65
68
  builder (>= 2.1.2)
66
69
  gyoku (~> 1.2)
@@ -68,21 +71,23 @@ GEM
68
71
  nokogiri (>= 1.8.1)
69
72
  nori (~> 2.4)
70
73
  wasabi (~> 3.4)
71
- simplecov (0.16.1)
74
+ simplecov (0.21.1)
72
75
  docile (~> 1.1)
73
- json (>= 1.8, < 3)
74
- simplecov-html (~> 0.10.0)
75
- simplecov-html (0.10.2)
76
+ simplecov-html (~> 0.11)
77
+ simplecov_json_formatter (~> 0.1)
78
+ simplecov-html (0.12.3)
79
+ simplecov_json_formatter (0.1.2)
76
80
  socksify (1.7.1)
77
- unicode-display_width (1.4.0)
78
- wasabi (3.5.0)
81
+ unicode-display_width (1.7.0)
82
+ wasabi (3.6.1)
83
+ addressable
79
84
  httpi (~> 2.0)
80
85
  nokogiri (>= 1.4.2)
81
- webmock (3.4.2)
86
+ webmock (3.11.0)
82
87
  addressable (>= 2.3.6)
83
88
  crack (>= 0.3.2)
84
- hashdiff
85
- yard (0.9.16)
89
+ hashdiff (>= 0.4.0, < 2.0.0)
90
+ yard (0.9.26)
86
91
 
87
92
  PLATFORMS
88
93
  ruby
@@ -100,4 +105,4 @@ DEPENDENCIES
100
105
  yard
101
106
 
102
107
  BUNDLED WITH
103
- 1.17.1
108
+ 1.17.3
@@ -1,7 +1,7 @@
1
1
  version: '3'
2
2
  services:
3
3
  console:
4
- image: ruby:2.3
4
+ image: ruby:2.5
5
5
  volumes:
6
6
  - .:/app:z
7
7
  hostname: varanus-dev
@@ -14,6 +14,39 @@ class Varanus
14
14
  @password = password
15
15
  end
16
16
 
17
+ # :nodoc:
18
+ def connection
19
+ @connection ||= Faraday.new(url: 'https://cert-manager.com/api',
20
+ request: { timeout: 300 }) do |conn|
21
+ conn.request :json
22
+ conn.response :json, content_type: /\bjson$/
23
+
24
+ conn.headers['login'] = @username
25
+ conn.headers['password'] = @password
26
+ conn.headers['customerUri'] = @customer_uri
27
+
28
+ conn.adapter Faraday.default_adapter
29
+ end
30
+ end
31
+
32
+ # Retrive DCV instance
33
+ # @return [Varanus::DCV]
34
+ def dcv
35
+ @dcv ||= DCV.new(self)
36
+ end
37
+
38
+ # Retrieve Domain instance
39
+ # @return [Varanus::Domain]
40
+ def domain
41
+ @domain ||= Domain.new(self)
42
+ end
43
+
44
+ # Retrieve Organization instance
45
+ # @return [Varanus::Organization]
46
+ def organization
47
+ @organization ||= Organization.new(self)
48
+ end
49
+
17
50
  # Retrieve Reports instance
18
51
  # @return [Varanus::Reports]
19
52
  def reports
@@ -35,6 +68,10 @@ require 'savon'
35
68
 
36
69
  # Require other files in this gem
37
70
  require 'varanus/error'
71
+ require 'varanus/rest_resource'
72
+ require 'varanus/dcv'
73
+ require 'varanus/domain'
74
+ require 'varanus/organization'
38
75
  require 'varanus/reports'
39
76
  require 'varanus/ssl'
40
77
  require 'varanus/ssl/csr'
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ # An connection to the DCV API. This should not be initialized directly. Instead,
4
+ # use Varanus#dcv
5
+ class Varanus::DCV < Varanus::RestResource
6
+ # Returns an Array of DCV information about searched for domains.
7
+ # This method will automatically page through all results
8
+ # @param opts [Hash] - all opts are optional
9
+ # @option opts [String] :domain Domain to search for
10
+ # @option opts [Integer] :org ID of organization
11
+ # @option opts [Integer] :department ID of department
12
+ # @option opts [String] :dcvStatus
13
+ # @option opts [String] :orderStatus
14
+ # @option opts [Integer] :expiresIn Expires in (days)
15
+ #
16
+ # Results will included an extra 'expiration_date_obj' if 'expirationDate' is in the
17
+ # response
18
+ def search opts = {}
19
+ get_with_size_and_position('dcv/v2/validation', opts).map(&method(:_format_status))
20
+ end
21
+
22
+ # Start domain validation process. This must be called before #submit is called
23
+ # @option domain [String] domain to validate
24
+ # @option type [String] Type of validation. Must be one of 'http', 'https', 'cname',
25
+ # or 'email'
26
+ def start domain, type
27
+ post("dcv/v1/validation/start/domain/#{type}", domain: domain)
28
+ end
29
+
30
+ # Retrieve DCV status for a single domain
31
+ # Result will included an extra 'expiration_date_obj' if 'expirationDate' is in the
32
+ # response
33
+ def status domain
34
+ _format_status(post('dcv/v2/validation/status', domain: domain))
35
+ end
36
+
37
+ # Submit domain validation for verficiation. This must be called after #start
38
+ # @option domain [String] domain to validate
39
+ # @option type [String] Type of validation. Must be one of 'http', 'https', 'cname',
40
+ # or 'email'
41
+ # @option email_address [String] This is required of +type+ is 'email'. Otherwise, it is
42
+ # ignored.
43
+ def submit domain, type, email_address = nil
44
+ if type.to_s == 'email'
45
+ raise ArgumentError, 'email_address must be specified' if email_address.nil?
46
+
47
+ post('dcv/v1/validation/submit/domain/email', domain: domain,
48
+ email: email_address)
49
+ else
50
+ post("dcv/v1/validation/submit/domain/#{type}", domain: domain)
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def _format_status status
57
+ return status unless status['expirationDate']
58
+
59
+ status.merge('expiration_date_obj' =>
60
+ Date.strptime(status['expirationDate'], '%Y-%m-%d'))
61
+ end
62
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A connection to the Domain API
4
+ class Varanus::Domain < Varanus::RestResource
5
+ # Create a new domain. The domain may need to be manually approved after this is
6
+ # called.
7
+ # +name+ is the domain
8
+ # +delegations+ is an Array of Hashes. Each Hash should have an 'orgId' and
9
+ # 'certTypes' key
10
+ # opts may include the following keys:
11
+ # - :description - optional - String
12
+ # - :active - optional - Boolean (defaults to +true+)
13
+ # - :allow_subdomains - optional - set to +false+ if you don't want to allow sub
14
+ # domains for this entry
15
+ #
16
+ # @returns [String] - URL for newly created domain
17
+ def create domain, delegations, opts = {}
18
+ opts = opts.dup
19
+ allow_subdomains = opts.delete(:allow_subdomains)
20
+ domain = "*.#{domain}" if allow_subdomains != false && !domain.start_with?('*.')
21
+
22
+ result = @varanus.connection.post('domain/v1',
23
+ opts.merge(name: domain, delegations: delegations))
24
+ check_result result
25
+ result.headers['Location']
26
+ end
27
+
28
+ # Return info on domain. +id+ must be the id returned by #list
29
+ def info id
30
+ get("domain/v1/#{id}")
31
+ end
32
+
33
+ def list opts = {}
34
+ get_with_size_and_position('domain/v1', opts)
35
+ end
36
+
37
+ def list_with_info opts = {}
38
+ domains = list(opts)
39
+ domains.map! { |domain| info(domain['id']) }
40
+ domains
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A connection to the Organization API
4
+ class Varanus::Organization < Varanus::RestResource
5
+ # Return info on organization.
6
+ def info id
7
+ get("organization/v1/#{id}")
8
+ end
9
+
10
+ def list
11
+ get('organization/v1')
12
+ end
13
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ # An abstract class for rest resources
4
+ # Rest resources should not be initialized directly. They should be created by methods
5
+ # on Varanus
6
+ class Varanus::RestResource
7
+ # :nodoc:
8
+ def initialize varanus
9
+ @varanus = varanus
10
+ end
11
+
12
+ private
13
+
14
+ def check_result result
15
+ body = result.body
16
+ return unless body.is_a?(Hash)
17
+ return if body['code'].nil?
18
+
19
+ klass = Varanus::Error
20
+ if body['code'] == 0 && body['description'] =~ /process/
21
+ klass = Varanus::Error::StillProcessing
22
+ end
23
+
24
+ raise klass.new(body['code'], body['description'])
25
+ end
26
+
27
+ def get path, *args
28
+ result = @varanus.connection.get(path, *args)
29
+ check_result result
30
+ result.body
31
+ end
32
+
33
+ # Performs multiple GETs with varying positions to ensure all results are returned.
34
+ def get_with_size_and_position path, opts = {}
35
+ size = opts[:size] || 200
36
+ position = opts[:position] || 0
37
+
38
+ results = []
39
+ loop do
40
+ params = { size: size, position: position }.merge(opts)
41
+ new_results = get(path, params)
42
+ results += new_results
43
+ break if new_results.length < size
44
+
45
+ position += size
46
+ end
47
+
48
+ results
49
+ end
50
+
51
+ def post path, *args
52
+ result = @varanus.connection.post(path, *args)
53
+ check_result result
54
+ result.body
55
+ end
56
+ end
@@ -2,35 +2,39 @@
2
2
 
3
3
  # An connection to the SSL/TSL API. This should not be initialized directly. Instead,
4
4
  # use Varanus#ssl
5
- class Varanus::SSL
6
- # @note Do not call this directly. Use {Varanus#ssl} to initialize
7
- def initialize varanus
8
- @varanus = varanus
9
- end
10
-
5
+ class Varanus::SSL < Varanus::RestResource
11
6
  # Returns the option from #certificate_types that best matches the csr.
12
7
  # @param csr [Varanus::SSL::CSR]
13
8
  # @return [Hash] The option from {#certificate_types} that best matches the csr
14
- def certificate_type_from_csr csr
15
- # first exclude certificate types we don't want
16
- types = certificate_types.reject do |ct|
17
- ct['name'] =~ /\b(?:EV|ECC|AMT|Elite)\b/
18
- end
19
- if csr.all_names.any? { |n| n.start_with?('*.') }
20
- types.find { |ct| ct['name'] =~ /Wildcard.+SSL/i }
21
- elsif csr.subject_alt_names.any?
22
- types.find { |ct| ct['name'] =~ /Multi.?Domain.+SSL/i }
23
- else
24
- types.find do |ct|
25
- ct['name'] =~ /\bSSL\b/ && ct['name'] !~ /(?:Multi.?Domain|Wildcard)/i
26
- end
9
+ def certificate_type_from_csr csr, days = nil
10
+ types = certificate_types_standard(days)
11
+ return types.first if types.length <= 1
12
+
13
+ regexp = cert_type_regexp(csr)
14
+ typ = types.find { |ct| ct['name'] =~ regexp } if regexp
15
+ return typ unless typ.nil?
16
+
17
+ types.find do |ct|
18
+ ct['name'] =~ /\bSSL\b/ && ct['name'] !~ /(?:Multi.?Domain|Wildcard)/i
27
19
  end
28
20
  end
29
21
 
30
22
  # Certificate types that can be used to sign a cert
31
23
  # @return [Array<Hash>]
32
24
  def certificate_types
33
- @certificate_types ||= get('types')
25
+ @certificate_types ||= get('ssl/v1/types')
26
+ end
27
+
28
+ # Return Array of certificate types based on standard sorting.
29
+ # @param days [Integer] if present, only include types that support the given day count
30
+ # @return [Array<Hash>]
31
+ def certificate_types_standard days = nil
32
+ types = certificate_types.reject do |ct|
33
+ ct['name'] =~ /\b(?:EV|ECC|AMT|Elite)\b/
34
+ end
35
+ types = types.select! { |t| t['terms'].include? days } unless days.nil?
36
+
37
+ types
34
38
  end
35
39
 
36
40
  # Retrieves the cert.
@@ -48,7 +52,16 @@ class Varanus::SSL
48
52
  # @raise [Varanus::Error::StillProcessing] Cert is still being signed
49
53
  # @return [String] Certificate
50
54
  def collect id, type = 'x509'
51
- get("collect/#{id}/#{type}")
55
+ get("ssl/v1/collect/#{id}/#{type}")
56
+ end
57
+
58
+ # Returns info on the SSL certificate of the given name
59
+ def info id
60
+ get("ssl/v1/#{id}")
61
+ end
62
+
63
+ def list opts = {}
64
+ get_with_size_and_position('ssl/v1', opts)
52
65
  end
53
66
 
54
67
  # Revoke an ssl cert
@@ -56,7 +69,7 @@ class Varanus::SSL
56
69
  # @param reason [String] Reason for revoking. Sectigo's API will return an error if it
57
70
  # is blank.
58
71
  def revoke id, reason
59
- post("revoke/#{id}", reason: reason)
72
+ post("ssl/v1/revoke/#{id}", reason: reason)
60
73
  nil
61
74
  end
62
75
 
@@ -75,6 +88,7 @@ class Varanus::SSL
75
88
  # specified, lowest allowed for the cert type will be used)
76
89
  # @return [Integer] Id of SSL cert.
77
90
  def sign csr, org_id, opts = {}
91
+ opts[:days] ||= opts[:years] * 365 unless opts[:years].nil?
78
92
  csr = Varanus::SSL::CSR.new(csr) unless csr.is_a?(Varanus::SSL::CSR)
79
93
  cert_type_id = opts_to_cert_type_id opts, csr
80
94
  args = {
@@ -87,42 +101,17 @@ class Varanus::SSL
87
101
  comments: opts[:comments].to_s[0, 1024],
88
102
  externalRequester: opts[:external_requester].to_s[0, 512]
89
103
  }
90
- post('enroll', args)['sslId']
104
+ post('ssl/v1/enroll', args)['sslId']
91
105
  end
92
106
 
93
107
  private
94
108
 
95
- def check_result result
96
- body = result.body
97
- return unless body.is_a?(Hash)
98
- return if body['code'].nil?
99
-
100
- klass = Varanus::Error
101
- if body['code'] == 0 && body['description'] =~ /process/
102
- klass = Varanus::Error::StillProcessing
103
- end
104
-
105
- raise klass.new(body['code'], body['description'])
106
- end
109
+ def cert_type_regexp csr
110
+ return /Wildcard.+SSL/i if csr.all_names.any? { |n| n.start_with?('*.') }
107
111
 
108
- def connection
109
- @connection ||= Faraday.new(url: 'https://cert-manager.com/api/ssl/v1',
110
- request: { timeout: 300 }) do |conn|
111
- conn.request :json
112
- conn.response :json, content_type: /\bjson$/
112
+ return /Multi.?Domain.+SSL/i if csr.subject_alt_names.any?
113
113
 
114
- conn.headers['login'] = @varanus.username
115
- conn.headers['password'] = @varanus.password
116
- conn.headers['customerUri'] = @varanus.customer_uri
117
-
118
- conn.adapter Faraday.default_adapter
119
- end
120
- end
121
-
122
- def get path
123
- result = connection.get(path)
124
- check_result result
125
- result.body
114
+ nil
126
115
  end
127
116
 
128
117
  def opts_to_cert_type_id opts, csr
@@ -132,19 +121,12 @@ class Varanus::SSL
132
121
  when String
133
122
  certificate_types.find { |ct| ct['name'] == opts[:cert_type] }['id']
134
123
  else
135
- certificate_type_from_csr(csr)['id']
124
+ certificate_type_from_csr(csr, opts[:days])['id']
136
125
  end
137
126
  end
138
127
 
139
- def post path, *args
140
- result = connection.post(path, *args)
141
- check_result result
142
- result.body
143
- end
144
-
145
128
  def opts_to_term opts, cert_type_id
146
129
  term = opts[:days]
147
- term ||= opts[:years] * 365 unless opts[:years].nil?
148
130
  term ||= certificate_types.find { |ct| ct['id'] == cert_type_id }['terms'].min
149
131
  term
150
132
  end
@@ -25,18 +25,23 @@ class Varanus::SSL::CSR
25
25
  request = OpenSSL::X509::Request.new
26
26
  request.version = 0
27
27
  request.subject = OpenSSL::X509::Name.parse subject.map { |k, v| "/#{k}=#{v}" }.join
28
+ request.add_attribute names_to_san_attribute(names)
29
+ request.public_key = key.public_key
30
+
31
+ request.sign(key, OpenSSL::Digest::SHA256.new)
32
+
33
+ [key, Varanus::SSL::CSR.new(request)]
34
+ end
28
35
 
29
- # Set Subject Alternate Names
36
+ # :nodoc:
37
+ # Create a Subject Alternate Names attribute from an Array of dns names
38
+ def self.names_to_san_attribute names
30
39
  ef = OpenSSL::X509::ExtensionFactory.new
31
40
  name_str = names.map { |n| "DNS:#{n}" }.join(', ')
32
41
  ext = ef.create_extension('subjectAltName', name_str, false)
33
42
  seq = OpenSSL::ASN1::Sequence([ext])
34
43
  ext_req = OpenSSL::ASN1::Set([seq])
35
- request.add_attribute OpenSSL::X509::Attribute.new('extReq', ext_req)
36
-
37
- request.public_key = key.public_key
38
- request.sign(key, OpenSSL::Digest::SHA256.new)
39
- [key, Varanus::SSL::CSR.new(request)]
44
+ OpenSSL::X509::Attribute.new('extReq', ext_req)
40
45
  end
41
46
 
42
47
  # Common Name (CN) for cert.
@@ -82,6 +87,8 @@ class Varanus::SSL::CSR
82
87
  @request.public_key.n.num_bytes * 8
83
88
  when OpenSSL::PKey::DSA
84
89
  @request.public_key.p.num_bytes * 8
90
+ when OpenSSL::PKey::EC
91
+ @request.public_key.group.degree
85
92
  else
86
93
  raise "Unknown public key type: #{@request.public_key.class}"
87
94
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Varanus
4
- VERSION = '0.2.1'
4
+ VERSION = '0.5.1'
5
5
  end
@@ -4,7 +4,6 @@ lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'varanus/version'
6
6
 
7
- # rubocop:disable Metrics/BlockLength
8
7
  Gem::Specification.new do |spec|
9
8
  spec.name = 'varanus'
10
9
  spec.version = Varanus::VERSION
@@ -28,7 +27,7 @@ Gem::Specification.new do |spec|
28
27
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
29
28
  end
30
29
  spec.require_paths = ['lib']
31
- spec.required_ruby_version = '>= 2.3.0'
30
+ spec.required_ruby_version = '>= 2.5.0'
32
31
 
33
32
  spec.add_development_dependency 'bundler', '~> 1.16'
34
33
  spec.add_development_dependency 'minitest', '~> 5.0'
@@ -44,4 +43,3 @@ Gem::Specification.new do |spec|
44
43
  spec.add_runtime_dependency 'faraday_middleware'
45
44
  spec.add_runtime_dependency 'savon', '~> 2.0'
46
45
  end
47
- # rubocop:enable Metrics/BlockLength
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: varanus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Dilda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-13 00:00:00.000000000 Z
11
+ date: 2021-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -204,8 +204,12 @@ files:
204
204
  - bin/setup
205
205
  - docker-compose.yml
206
206
  - lib/varanus.rb
207
+ - lib/varanus/dcv.rb
208
+ - lib/varanus/domain.rb
207
209
  - lib/varanus/error.rb
210
+ - lib/varanus/organization.rb
208
211
  - lib/varanus/reports.rb
212
+ - lib/varanus/rest_resource.rb
209
213
  - lib/varanus/ssl.rb
210
214
  - lib/varanus/ssl/csr.rb
211
215
  - lib/varanus/version.rb
@@ -222,15 +226,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
222
226
  requirements:
223
227
  - - ">="
224
228
  - !ruby/object:Gem::Version
225
- version: 2.3.0
229
+ version: 2.5.0
226
230
  required_rubygems_version: !ruby/object:Gem::Requirement
227
231
  requirements:
228
232
  - - ">="
229
233
  - !ruby/object:Gem::Version
230
234
  version: '0'
231
235
  requirements: []
232
- rubyforge_project:
233
- rubygems_version: 2.7.8
236
+ rubygems_version: 3.0.3
234
237
  signing_key:
235
238
  specification_version: 4
236
239
  summary: Interface for Sectigo's (formerly Comodo CA) API.