varanus 0.7.1 → 0.8.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
  SHA256:
3
- metadata.gz: 271baf219a1247e588a20aba506a76e26668bad6c6ab55546f75fa697d04e3ff
4
- data.tar.gz: 00c5bc35eeb4b56fdc94b18d969c7ac498ffc87a948db20fdc989fc4e90cf8d6
3
+ metadata.gz: 9c5717bc294e05caa49007dbf36c638ecf3a1d3e192aee421e51a73fec58246c
4
+ data.tar.gz: 54f6feea0b5b692d415dd2f9d5eff9d0d088f29e26d54a700467494f11904048
5
5
  SHA512:
6
- metadata.gz: 70898c1f830700b0a2865656143c452dfeae4b9846e9c1b4730c5cd359d2c4f786e167758581d2028fc2c60588480382066cecc932d03b7355accb84ff21a0c3
7
- data.tar.gz: de4d6791505e36cbaa157a0004e2405b90f1067c0953a892a0efb6fc622b671744779603620b3c142413043e4063cbd411cf2629acb3256a7fccc308e8be93ee
6
+ metadata.gz: 246eeabfd08d59b01f5b8e6cca4d5ec8b4c7a73223ee34d8ac86a1d459d286fdf965ed410a381b2312ab72e97f3c0b65dc0da77c8b31776e53253f10b9003a05
7
+ data.tar.gz: cdf0e60e8894b50e55f81901f0d441a7a3edf376856de12ea4a0bfc845267c3026926dcafabec14e7aebaf1292a25e6c8c0e76cbdfd9f346a9b18a3828021543
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.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Dilda
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-31 00:00:00.000000000 Z
11
+ date: 2024-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
19
+ version: '2.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.16'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -189,36 +189,12 @@ email:
189
189
  executables: []
190
190
  extensions: []
191
191
  extra_rdoc_files: []
192
- files:
193
- - ".codeclimate.yml"
194
- - ".gitignore"
195
- - ".rubocop.yml"
196
- - ".travis.yml"
197
- - CHANGELOG.md
198
- - Gemfile
199
- - Gemfile.lock
200
- - LICENSE.txt
201
- - README.md
202
- - Rakefile
203
- - bin/console
204
- - bin/setup
205
- - docker-compose.yml
206
- - lib/varanus.rb
207
- - lib/varanus/dcv.rb
208
- - lib/varanus/domain.rb
209
- - lib/varanus/error.rb
210
- - lib/varanus/organization.rb
211
- - lib/varanus/reports.rb
212
- - lib/varanus/rest_resource.rb
213
- - lib/varanus/ssl.rb
214
- - lib/varanus/ssl/csr.rb
215
- - lib/varanus/version.rb
216
- - varanus.gemspec
192
+ files: []
217
193
  homepage: https://github.com/duke-automation/varanus
218
194
  licenses:
219
195
  - MIT
220
196
  metadata: {}
221
- post_install_message:
197
+ post_install_message:
222
198
  rdoc_options: []
223
199
  require_paths:
224
200
  - lib
@@ -233,8 +209,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
233
209
  - !ruby/object:Gem::Version
234
210
  version: '0'
235
211
  requirements: []
236
- rubygems_version: 3.0.3
237
- signing_key:
212
+ rubygems_version: 3.3.27
213
+ signing_key:
238
214
  specification_version: 4
239
215
  summary: Interface for Sectigo's (formerly Comodo CA) API.
240
216
  test_files: []
data/.codeclimate.yml DELETED
@@ -1,4 +0,0 @@
1
- plugins:
2
- rubocop:
3
- enabled: true
4
- channel: rubocop-0-59
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- /test.rb
data/.rubocop.yml DELETED
@@ -1,51 +0,0 @@
1
- AllCops:
2
- NewCops: disable
3
- TargetRubyVersion: 2.5
4
-
5
- Bundler/OrderedGems:
6
- AutoCorrect: false
7
-
8
- Layout/LineLength:
9
- Max: 90
10
- Exclude:
11
- - 'test/**/*'
12
-
13
- Metrics/AbcSize:
14
- Max: 25
15
- Exclude:
16
- - 'test/**/*'
17
-
18
- Metrics/ClassLength:
19
- Max: 125
20
- Exclude:
21
- - 'test/**/*'
22
-
23
- Metrics/MethodLength:
24
- Max: 20
25
- Exclude:
26
- - 'test/**/*'
27
-
28
- Naming/FileName:
29
- Exclude:
30
- - Gemfile
31
-
32
- Style/ClassAndModuleChildren:
33
- EnforcedStyle: compact
34
-
35
- Style/ConditionalAssignment:
36
- Enabled: false
37
-
38
- Style/MethodDefParentheses:
39
- EnforcedStyle: require_no_parentheses_except_multiline
40
-
41
- Style/NumericPredicate:
42
- EnforcedStyle: comparison
43
-
44
- Style/RescueModifier:
45
- AutoCorrect: false
46
-
47
- Style/SymbolArray:
48
- EnforcedStyle: brackets
49
-
50
- Style/WordArray:
51
- EnforcedStyle: brackets
data/.travis.yml DELETED
@@ -1,18 +0,0 @@
1
- ---
2
- env:
3
- global:
4
- - CC_TEST_REPORTER_ID=11ec0aee76479858801566bb43fd7d76eced4cbb2432bcead71db59dae21eaae
5
- sudo: false
6
- language: ruby
7
- cache: bundler
8
- rvm:
9
- - 2.5
10
- - 2.6
11
- - 2.7
12
- before_install: gem install bundler -v 1.16.5
13
- before_script:
14
- - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
15
- - chmod +x ./cc-test-reporter
16
- - ./cc-test-reporter before-build
17
- after_script:
18
- - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
data/CHANGELOG.md DELETED
@@ -1,38 +0,0 @@
1
- ### Version 0.7.1 (2022-01-31)
2
- * Varanus::SSL#certificate_types_standard - also exclude 'Extended Validation'
3
-
4
- ### Version 0.7.0 (2020-02-03)
5
- * Add Varanus::Domain#report
6
-
7
- ### Version 0.6.0 (2020-02-01)
8
- * Add Varanus::SSL#report
9
- * Varanus::Reports (Varanus#reports) is now deprecated.
10
-
11
- ### Version 0.5.1 (2021-01-28)
12
- * Varanus::SSL::CSR - support EC certs
13
-
14
- ### Version 0.5.0 (2021-01-26)
15
- * Add Varanus::Domain
16
- * Add Varanus::SSL#list and Varanus::SSL#info
17
- * Add Varanus::Organization
18
-
19
- ### 0.4.0 (2021-01-06)
20
- * Add Varanus::DCV
21
-
22
- ### 0.3.1 (2020-10-14)
23
- * Fix issue when Sectigo reports two identical 'Short Life' certs
24
-
25
- ### 0.3.0 (2020-08-24)
26
- * Add support for new 'Short Life' certs
27
-
28
- ### 0.2.1 (2018-11-13)
29
- * Increase timeout value for SSL requests
30
-
31
- ### 0.2.0 (2018-11-09)
32
- * Added Varanus::SSL::CSR.generate
33
- * Added Reports
34
- * Varanus::Reports#ssl - list of SSL/TLS certs
35
- * Varanus::Reports#domains - list of domains validated with DCV
36
-
37
- ### 0.1.0 (2018-11-07)
38
- * Initial release
data/Gemfile DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
-
7
- # Specify your gem's dependencies in varanus.gemspec
8
- gemspec
data/Gemfile.lock DELETED
@@ -1,108 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- varanus (0.7.1)
5
- faraday
6
- faraday_middleware
7
- savon (~> 2.0)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- addressable (2.7.0)
13
- public_suffix (>= 2.0.2, < 5.0)
14
- akami (1.3.1)
15
- gyoku (>= 0.4.0)
16
- nokogiri
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)
24
- multipart-post (>= 1.2, < 3)
25
- ruby2_keywords
26
- faraday-net_http (1.0.0)
27
- faraday_middleware (1.0.0)
28
- faraday (~> 1.0)
29
- gyoku (1.3.1)
30
- builder (>= 2.1.2)
31
- hashdiff (1.0.1)
32
- httpi (2.4.5)
33
- rack
34
- socksify
35
- minitest (5.14.3)
36
- minitest-rg (5.2.0)
37
- minitest (~> 5.0)
38
- mocha (1.12.0)
39
- multipart-post (2.1.1)
40
- nokogiri (1.11.1-x86_64-linux)
41
- racc (~> 1.4)
42
- nori (2.6.0)
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)
49
- rainbow (3.0.0)
50
- rake (10.5.0)
51
- regexp_parser (2.0.3)
52
- rexml (3.2.4)
53
- rubocop (1.7.0)
54
- parallel (~> 1.10)
55
- parser (>= 2.7.1.5)
56
- rainbow (>= 2.2.2, < 4.0)
57
- regexp_parser (>= 1.8, < 3.0)
58
- rexml
59
- rubocop-ast (>= 1.2.0, < 2.0)
60
- ruby-progressbar (~> 1.7)
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)
67
- akami (~> 1.2)
68
- builder (>= 2.1.2)
69
- gyoku (~> 1.2)
70
- httpi (~> 2.3)
71
- nokogiri (>= 1.8.1)
72
- nori (~> 2.4)
73
- wasabi (~> 3.4)
74
- simplecov (0.21.1)
75
- docile (~> 1.1)
76
- simplecov-html (~> 0.11)
77
- simplecov_json_formatter (~> 0.1)
78
- simplecov-html (0.12.3)
79
- simplecov_json_formatter (0.1.2)
80
- socksify (1.7.1)
81
- unicode-display_width (1.7.0)
82
- wasabi (3.6.1)
83
- addressable
84
- httpi (~> 2.0)
85
- nokogiri (>= 1.4.2)
86
- webmock (3.11.0)
87
- addressable (>= 2.3.6)
88
- crack (>= 0.3.2)
89
- hashdiff (>= 0.4.0, < 2.0.0)
90
- yard (0.9.26)
91
-
92
- PLATFORMS
93
- ruby
94
-
95
- DEPENDENCIES
96
- bundler (~> 1.16)
97
- minitest (~> 5.0)
98
- minitest-rg
99
- mocha
100
- rake (~> 10.0)
101
- rubocop
102
- simplecov
103
- varanus!
104
- webmock
105
- yard
106
-
107
- BUNDLED WITH
108
- 1.17.3
data/LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2018 Duke University
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
data/README.md DELETED
@@ -1,104 +0,0 @@
1
- # Varanus
2
-
3
- This gem provides an interface to Sectigo's (formerly Comodo CA) APIs for working
4
- with SSL/TLS certificates as well as its reporting API.
5
-
6
- Support for Sectigo's other APIs (S/MIME, code signing, device certificates, etc) may
7
- be added at a later date. Merge requests to add some of this functionality would be
8
- greatly appreciated.
9
-
10
- [![Build Status](https://travis-ci.org/duke-automation/varanus.svg?branch=master)](https://travis-ci.org/duke-automation/varanus)
11
- [![Gem Version](https://badge.fury.io/rb/varanus.svg)](http://badge.fury.io/rb/varanus)
12
- [![Maintainability](https://api.codeclimate.com/v1/badges/593ef1aa2ba757b5374f/maintainability)](https://codeclimate.com/github/duke-automation/varanus/maintainability)
13
- [![Test Coverage](https://api.codeclimate.com/v1/badges/593ef1aa2ba757b5374f/test_coverage)](https://codeclimate.com/github/duke-automation/varanus/test_coverage)
14
-
15
- ## Usage
16
-
17
- #### Generate and sign SSL cert
18
-
19
- ```ruby
20
- key, csr = Varanus::SSL::CSR.generate(['example.com'])
21
- varanus = Varanus.new(customer_uri, username, password)
22
- id = varanus.ssl.sign csr, org_id
23
- begin
24
- cert = varanus.ssl.collect id
25
- rescue Varanus::Error::StillProcessing
26
- sleep 1
27
- retry
28
- end
29
- puts key
30
- puts cert
31
- ```
32
-
33
- #### Sign SSL cert from CSR
34
-
35
- ```ruby
36
- csr = File.read('/path/to/file.csr')
37
- varanus = Varanus.new(customer_uri, username, password)
38
- id = varanus.ssl.sign csr, org_id
39
- begin
40
- cert = varanus.ssl.collect id
41
- rescue Varanus::Error::StillProcessing
42
- sleep 1
43
- retry
44
- end
45
- puts cert
46
- ```
47
-
48
- #### Revoke SSL cert
49
-
50
- ```ruby
51
- Varanus.new(customer_uri, username, password).ssl.revoke(id)
52
- ```
53
-
54
- #### Reports
55
-
56
- Report on all SSL certs
57
- ```ruby
58
- pp Varanus.new(customer_uri, usernams, password).reports.ssl
59
- ```
60
-
61
- Report on all domains (DCV status)
62
- ```ruby
63
- pp Varanus.new(customer_uri, usernams, password).reports.domains
64
- ```
65
-
66
- #### Authentication
67
-
68
- Authentication requires the same credentials you use to login to cert-manager.com as well as the ```customer_uri```. If your URL to log into cert-manager.com is https://cert-manager.com/customer/MyCompany then your ```customer_uri``` will be ```'MyCompany'```
69
-
70
- #### Finding Organization Id (org_id)
71
-
72
- Signing a cert requires specifying an ```org_id```. Each department in cert-manager.com has an associated ```org_id```.
73
-
74
- To find the ```org_id```, log into cert-manager.com, go to **Settings** -> **Departments**, then click to edit the department you are interested in. The value you want is in the **OrgID** field.
75
-
76
- ## Installation
77
-
78
- Add this line to your application's Gemfile:
79
-
80
- ```ruby
81
- gem 'varanus'
82
- ```
83
-
84
- And then execute:
85
-
86
- $ bundle
87
-
88
- Or install it yourself as:
89
-
90
- $ gem install varanus
91
-
92
- ## Development
93
-
94
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
95
-
96
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
97
-
98
- ## Contributing
99
-
100
- Bug reports and pull requests are welcome on GitHub at https://github.com/duke-automation/varanus.
101
-
102
- ## License
103
-
104
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile DELETED
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rake/testtask'
5
-
6
- Rake::TestTask.new(:test) do |t|
7
- t.libs << 'test'
8
- t.libs << 'lib'
9
- t.test_files = FileList['test/**/*_test.rb']
10
- end
11
-
12
- task default: :test
data/bin/console DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'bundler/setup'
5
- require 'varanus'
6
-
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- # require "pry"
12
- # Pry.start
13
-
14
- require 'irb'
15
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/docker-compose.yml DELETED
@@ -1,11 +0,0 @@
1
- version: '3'
2
- services:
3
- console:
4
- image: ruby:2.5
5
- volumes:
6
- - .:/app:z
7
- hostname: varanus-dev
8
- working_dir: /app
9
- stdin_open: true
10
- tty: true
11
- command: bash -c './bin/setup && ./bin/console'
data/lib/varanus/dcv.rb DELETED
@@ -1,62 +0,0 @@
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
@@ -1,46 +0,0 @@
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
-
43
- def report
44
- post('report/v1/domains', {})['reports']
45
- end
46
- end
data/lib/varanus/error.rb DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Error returned from the Sectigo API
4
- class Varanus::Error < StandardError
5
- # @return [Integer] Code associated with error
6
- attr_reader :code
7
-
8
- def initialize code, msg
9
- @code = code
10
- super(msg)
11
- end
12
- end
13
-
14
- # Certificate is still being signed.
15
- class Varanus::Error::StillProcessing < Varanus::Error; end
@@ -1,13 +0,0 @@
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
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # An connection to the Reports API. This should not be initialized directly. Instead,
4
- # use Varanus#reports
5
- class Varanus::Reports
6
- SSL_CERT_STATUSES = {
7
- any: 0,
8
- requested: 1,
9
- downloaded: 2,
10
- revoked: 3,
11
- expired: 4,
12
- pending_download: 5,
13
- not_enrolled: 6
14
- }.freeze
15
-
16
- # @note Do not call this directly. Use {Varanus#reports} to initialize
17
- def initialize varanus
18
- @varanus = varanus
19
- end
20
-
21
- # DEPRECATED: Please use Varanus::Domain#list_with_info instead.
22
- def domains
23
- warn 'DEPRECATION WARNING: Varanus::Reports#domains is deprecated. ' \
24
- 'Use Varanus::Domain#report instead'
25
- r = soap_call :get_domain_report, {}
26
- format_results r[:report_row_domains]
27
- end
28
-
29
- # DEPRECATED: Please use Varanus::SSL#report instead.
30
- def ssl opts = {}
31
- warn 'DEPRECATION WARNING: Varanus::Reports#ssl is deprecated. ' \
32
- 'Use Varanus::SSL#report instead'
33
-
34
- msg = { organizationNames: nil, certificateStatus: 0 }
35
-
36
- msg[:organizationNames] = Array(opts[:orgs]).join(',') if opts.include? :orgs
37
- if opts.include? :status
38
- msg[:certificateStatus] = SSL_CERT_STATUSES[opts[:status]]
39
- raise ArgumentError, 'Invalid status' if msg[:certificateStatus].nil?
40
- end
41
-
42
- r = soap_call :get_SSL_report, msg
43
- format_results r[:reports]
44
- end
45
-
46
- private
47
-
48
- def format_results results
49
- if results.is_a? Hash
50
- [results]
51
- else
52
- results.to_a
53
- end
54
- end
55
-
56
- def savon
57
- @savon ||= Savon.client(
58
- namespace: 'http://report.ws.epki.comodo.com/',
59
- endpoint: 'https://cert-manager.com:443/ws/ReportService',
60
- log: false
61
- )
62
- end
63
-
64
- def soap_call func, opts = {}
65
- msg = opts.dup
66
- msg[:authData] = { customerLoginUri: @varanus.customer_uri, login: @varanus.username,
67
- password: @varanus.password }
68
-
69
- result = savon.call func, message: msg
70
- result.body[(func.to_s.downcase + '_response').to_sym][:return]
71
- end
72
- end
@@ -1,56 +0,0 @@
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
@@ -1,131 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Wrapper class around a OpenSSL::X509::Request
4
- # Provides helper functions to make reading information from the CSR easier
5
- class Varanus::SSL::CSR
6
- # Key size used when calling {.generate}
7
- DEFAULT_KEY_SIZE = 4096
8
-
9
- # Generate a CSR
10
- # @param names [Array<String>] List of DNS names. The first one will be the CN
11
- # @param key [OpenSSL::PKey::RSA, OpenSSL::PKey::DSA, nil] Secret key for the cert.
12
- # A DSA key will be generated if +nil+ is passed in.
13
- # @param subject [Hash] Options for the subject of the cert. By default only CN will
14
- # be set
15
- # @return [Array(OpenSSL::PKey::PKey, Varanus::SSL::CSR)] The private key for the cert
16
- # and CSR
17
- def self.generate names, key = nil, subject = {}
18
- raise ArgumentError, 'names cannot be empty' if names.empty?
19
-
20
- subject = subject.dup
21
- subject['CN'] = names.first
22
-
23
- key ||= OpenSSL::PKey::DSA.new(DEFAULT_KEY_SIZE)
24
-
25
- request = OpenSSL::X509::Request.new
26
- request.version = 0
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.new('SHA256'))
32
-
33
- [key, Varanus::SSL::CSR.new(request)]
34
- end
35
-
36
- # :nodoc:
37
- # Create a Subject Alternate Names attribute from an Array of dns names
38
- def self.names_to_san_attribute names
39
- ef = OpenSSL::X509::ExtensionFactory.new
40
- name_str = names.map { |n| "DNS:#{n}" }.join(', ')
41
- ext = ef.create_extension('subjectAltName', name_str, false)
42
- seq = OpenSSL::ASN1::Sequence([ext])
43
- ext_req = OpenSSL::ASN1::Set([seq])
44
- OpenSSL::X509::Attribute.new('extReq', ext_req)
45
- end
46
-
47
- # Common Name (CN) for cert.
48
- # @return [String]
49
- attr_reader :cn
50
-
51
- # OpenSSL::X509::Request representation of CSR
52
- # @return [OpenSSL::X509::Request]
53
- attr_reader :request
54
-
55
- # @param csr [String, OpenSSL::X509::Request]
56
- def initialize csr
57
- if csr.is_a? OpenSSL::X509::Request
58
- @request = csr
59
- @text = csr.to_s
60
- else
61
- @text = csr.to_s
62
- @request = OpenSSL::X509::Request.new @text
63
- end
64
-
65
- raise 'Improperly signed CSR' unless @request.verify @request.public_key
66
-
67
- cn_ref = @request.subject.to_a.find { |a| a[0] == 'CN' }
68
- @cn = cn_ref && cn_ref[1].downcase
69
-
70
- _parse_sans
71
-
72
- # If we have no CN or SAN, raise an error
73
- raise 'CSR must have a CN and/or subjectAltName' if @cn.nil? && @sans.empty?
74
- end
75
-
76
- # Unique list of all DNS names for cert (CN and subject alt names)
77
- # @return [Array<String>]
78
- def all_names
79
- ([@cn] + @sans).compact.uniq
80
- end
81
-
82
- # Key size for the cert
83
- # @return [Integer]
84
- def key_size
85
- case @request.public_key
86
- when OpenSSL::PKey::RSA
87
- @request.public_key.n.num_bytes * 8
88
- when OpenSSL::PKey::DSA
89
- @request.public_key.p.num_bytes * 8
90
- when OpenSSL::PKey::EC
91
- @request.public_key.group.degree
92
- else
93
- raise "Unknown public key type: #{@request.public_key.class}"
94
- end
95
- end
96
-
97
- # PEM format for cert
98
- def to_s
99
- @text
100
- end
101
-
102
- # DNS subject alt names
103
- # @return [Array<String>]
104
- def subject_alt_names
105
- @sans
106
- end
107
-
108
- private
109
-
110
- def _parse_sans
111
- extensions = @request.attributes.select { |at| at.oid == 'extReq' }
112
- sans_extensions = extensions.flat_map do |extension|
113
- extension.value.value[0].value
114
- .select { |ext| ext.first.value == 'subjectAltName' }
115
- .map { |ext| ext.value.last }
116
- end
117
- @sans = sans_extensions.compact.flat_map do |san|
118
- _parse_sans_extension san
119
- end
120
- end
121
-
122
- def _parse_sans_extension ext
123
- OpenSSL::ASN1.decode(ext.value).map do |s_entry|
124
- unless s_entry.tag == 2 && s_entry.tag_class == :CONTEXT_SPECIFIC
125
- raise "unknown tag #{s_entry.tag}"
126
- end
127
-
128
- s_entry.value.downcase
129
- end
130
- end
131
- end
data/lib/varanus/ssl.rb DELETED
@@ -1,191 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # An connection to the SSL/TSL API. This should not be initialized directly. Instead,
4
- # use Varanus#ssl
5
- class Varanus::SSL < Varanus::RestResource
6
- # rubocop:disable Style/MutableConstant
7
- # These constants are frozen, rubocop is failing to detect the freeze.
8
- # See https://github.com/rubocop-hq/rubocop/issues/4406
9
- REPORT_CERT_STATUS = { any: 0, requested: 1, issued: 2, revoked: 3, expired: 4 }
10
- REPORT_CERT_STATUS.default_proc = proc { |_h, k|
11
- raise ArgumentError, "Unknown certificateStatus: #{k.inspect}"
12
- }
13
- REPORT_CERT_STATUS.freeze
14
-
15
- REPORT_CERT_DATE_ATTR = { revocation_date: 2, expiration_date: 3, request_date: 4,
16
- issue_date: 5 }
17
- REPORT_CERT_DATE_ATTR.default_proc = proc { |_h, k|
18
- raise ArgumentError, "Unknown certificateDateAttribute: #{k.inspect}"
19
- }
20
- REPORT_CERT_DATE_ATTR.freeze
21
- # rubocop:enable Style/MutableConstant
22
-
23
- # Returns the option from #certificate_types that best matches the csr.
24
- # @param csr [Varanus::SSL::CSR]
25
- # @return [Hash] The option from {#certificate_types} that best matches the csr
26
- def certificate_type_from_csr csr, days = nil
27
- types = certificate_types_standard(days)
28
- return types.first if types.length <= 1
29
-
30
- regexp = cert_type_regexp(csr)
31
- typ = types.find { |ct| ct['name'] =~ regexp } if regexp
32
- return typ unless typ.nil?
33
-
34
- types.find do |ct|
35
- ct['name'] =~ /\bSSL\b/ && ct['name'] !~ /(?:Multi.?Domain|Wildcard)/i
36
- end
37
- end
38
-
39
- # Certificate types that can be used to sign a cert
40
- # @return [Array<Hash>]
41
- def certificate_types
42
- @certificate_types ||= get('ssl/v1/types')
43
- end
44
-
45
- # Return Array of certificate types based on standard sorting.
46
- # @param days [Integer] if present, only include types that support the given day count
47
- # @return [Array<Hash>]
48
- def certificate_types_standard days = nil
49
- types = certificate_types.reject do |ct|
50
- ct['name'] =~ /\b(?:EV|Extended Validation|ECC|AMT|Elite)\b/
51
- end
52
- types = types.select! { |t| t['terms'].include? days } unless days.nil?
53
-
54
- types
55
- end
56
-
57
- # Retrieves the cert.
58
- # @param id [Integer] As returned by {#sign}
59
- # @param type [String]
60
- #
61
- # +type+ can be one of:
62
- # 'x509' - X509 format - cert and chain (default)
63
- # 'x509CO' - X509 format - cert only
64
- # 'x509IO' - X509 format - intermediates/root only
65
- # 'x590IOR' - X509 format - intermediates/root only reversed
66
- # 'base64' - PKCS#7 base64 encoded
67
- # 'bin' - PKCS#7 bin encoded
68
- #
69
- # @raise [Varanus::Error::StillProcessing] Cert is still being signed
70
- # @return [String] Certificate
71
- def collect id, type = 'x509'
72
- get("ssl/v1/collect/#{id}/#{type}")
73
- end
74
-
75
- # Returns info on the SSL certificate of the given name
76
- def info id
77
- get("ssl/v1/#{id}")
78
- end
79
-
80
- # List certs ids and serial numbers
81
- def list opts = {}
82
- get_with_size_and_position('ssl/v1', opts)
83
- end
84
-
85
- # Return a report (list) of SSL certs based on the options.
86
- # The report includes a full set of details about the certs, not just the id/cn/serial
87
- # +opts+ can include:
88
- # (all are optional)
89
- # - :organizationIds - Array - ids of organization/departments to include certs for
90
- # - :certificateStatus - :any, :requested, :issued, :revoked, or :expired
91
- # - :certificateDateAttribute - Specifies what fields :from and/or :to refer to.
92
- # Can be: :revocation_date, :expiration_date,
93
- # :request_date, or :issue_date
94
- # - :from - Date - based on :certificateDateAttribute
95
- # - :to - Date - based on :certificateDateAttribute
96
- def report opts = { certificateStatus: :any }
97
- # Default is to request any certificate status since the API call will fail if no
98
- # options are passed
99
- opts = { certificateStatus: :any } if opts.empty?
100
- opts = _parse_report_opts(opts)
101
-
102
- post('report/v1/ssl-certificates', opts)['reports']
103
- end
104
-
105
- # Revoke an ssl cert
106
- # @param id [Integer] As returned by {#sign}
107
- # @param reason [String] Reason for revoking. Sectigo's API will return an error if it
108
- # is blank.
109
- def revoke id, reason
110
- post("ssl/v1/revoke/#{id}", reason: reason)
111
- nil
112
- end
113
-
114
- # Sign an SSL cert. Returns the id of the SSL cert
115
- # @param csr [Varanus::SSL::CSR, OpenSSL::X509::Request, String] CSR to sign
116
- # @param org_id [Integer] your organization id on cert-manager.com
117
- # @param opts [Hash]
118
- # @option opts [String] :comments ('') Limited to 1,024 characters
119
- # @option opts [String] :external_requester ('') email address associated with cert on
120
- # cert-manager.com - limited to 512 characters
121
- # @option opts [String, Integer] :cert_type name(String) or id(Integer) of the cert
122
- # type to use. If none is specified, Varanus will attempt to find one
123
- # @option opts [Integer] :years number of years cert should be valid for (this number
124
- # is multiplied by 365 and used as days)
125
- # @option opts [Integer] :days number of days cert should be valid for (if none is
126
- # specified, lowest allowed for the cert type will be used)
127
- # @return [Integer] Id of SSL cert.
128
- def sign csr, org_id, opts = {}
129
- opts[:days] ||= opts[:years] * 365 unless opts[:years].nil?
130
- csr = Varanus::SSL::CSR.new(csr) unless csr.is_a?(Varanus::SSL::CSR)
131
- cert_type_id = opts_to_cert_type_id opts, csr
132
- args = {
133
- orgId: org_id,
134
- csr: csr.to_s,
135
- subjAltNames: csr.subject_alt_names.join(','),
136
- certType: cert_type_id,
137
- term: opts_to_term(opts, cert_type_id),
138
- serverType: -1,
139
- comments: opts[:comments].to_s[0, 1024],
140
- externalRequester: opts[:external_requester].to_s[0, 512]
141
- }
142
- post('ssl/v1/enroll', args)['sslId']
143
- end
144
-
145
- private
146
-
147
- def cert_type_regexp csr
148
- return /Wildcard.+SSL/i if csr.all_names.any? { |n| n.start_with?('*.') }
149
-
150
- return /Multi.?Domain.+SSL/i if csr.subject_alt_names.any?
151
-
152
- nil
153
- end
154
-
155
- def opts_to_cert_type_id opts, csr
156
- case opts[:cert_type]
157
- when Integer
158
- opts[:cert_type]
159
- when String
160
- certificate_types.find { |ct| ct['name'] == opts[:cert_type] }['id']
161
- else
162
- certificate_type_from_csr(csr, opts[:days])['id']
163
- end
164
- end
165
-
166
- def opts_to_term opts, cert_type_id
167
- term = opts[:days]
168
- term ||= certificate_types.find { |ct| ct['id'] == cert_type_id }['terms'].min
169
- term
170
- end
171
-
172
- def _parse_report_opts user_opts
173
- api_opts = {}
174
- user_opts.each do |key, val|
175
- case key
176
- when :organizationIds, :certificateRequestSource, :serialNumberFormat
177
- api_opts[key] = val
178
- when :from, :to
179
- api_opts[key] = val.strftime('%Y-%m-%d')
180
- when :certificateStatus
181
- api_opts[key] = REPORT_CERT_STATUS[val]
182
- when :certificateDateAttribute
183
- api_opts[key] = REPORT_CERT_DATE_ATTR[val]
184
- else
185
- raise ArgumentError, "Unknown key: #{key.inspect}"
186
- end
187
- end
188
-
189
- api_opts
190
- end
191
- end
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Varanus
4
- VERSION = '0.7.1'
5
- end
data/lib/varanus.rb DELETED
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Interface for Sectigo's (formerly Comodo CA) API.
4
- class Varanus
5
- attr_reader :customer_uri, :username, :password
6
-
7
- # @param customer_uri [String]
8
- # (see {file:README.md#label-Finding+Organization+Id+-28org_id-29})
9
- # @param username [String]
10
- # @param password [String]
11
- def initialize customer_uri, username, password
12
- @customer_uri = customer_uri
13
- @username = username
14
- @password = password
15
- end
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
-
50
- # DEPRECATED
51
- def reports
52
- @reports ||= Reports.new(self)
53
- end
54
-
55
- # Retrive SSL instance
56
- # @return [Varanus::SSL]
57
- def ssl
58
- @ssl ||= SSL.new(self)
59
- end
60
- end
61
-
62
- # stdlib/gem requires
63
- require 'faraday'
64
- require 'faraday_middleware'
65
- require 'openssl'
66
- require 'savon'
67
-
68
- # Require other files in this gem
69
- require 'varanus/error'
70
- require 'varanus/rest_resource'
71
- require 'varanus/dcv'
72
- require 'varanus/domain'
73
- require 'varanus/organization'
74
- require 'varanus/reports'
75
- require 'varanus/ssl'
76
- require 'varanus/ssl/csr'
77
- require 'varanus/version'
data/varanus.gemspec DELETED
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- lib = File.expand_path('lib', __dir__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'varanus/version'
6
-
7
- Gem::Specification.new do |spec|
8
- spec.name = 'varanus'
9
- spec.version = Varanus::VERSION
10
- spec.authors = ['Sean Dilda']
11
- spec.email = ['sean@duke.edu']
12
-
13
- spec.summary = "Interface for Sectigo's (formerly Comodo CA) API."
14
- spec.description = <<~DESCRIPTION
15
- This gem provides an interface to Sectigo's (formerly Comodo CA) APIs for working
16
- with SSL/TLS certificates as well as its reporting API.
17
-
18
- Support for Sectigo's other APIs (S/MIME, code signing, device certificates, etc) may
19
- be added at a later date.
20
- DESCRIPTION
21
- spec.homepage = 'https://github.com/duke-automation/varanus'
22
- spec.license = 'MIT'
23
-
24
- # Specify which files should be added to the gem when it is released.
25
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
26
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
27
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
28
- end
29
- spec.require_paths = ['lib']
30
- spec.required_ruby_version = '>= 2.5.0'
31
-
32
- spec.add_development_dependency 'bundler', '~> 1.16'
33
- spec.add_development_dependency 'minitest', '~> 5.0'
34
- spec.add_development_dependency 'minitest-rg'
35
- spec.add_development_dependency 'mocha'
36
- spec.add_development_dependency 'rake', '~> 10.0'
37
- spec.add_development_dependency 'rubocop'
38
- spec.add_development_dependency 'simplecov'
39
- spec.add_development_dependency 'webmock'
40
- spec.add_development_dependency 'yard'
41
-
42
- spec.add_runtime_dependency 'faraday'
43
- spec.add_runtime_dependency 'faraday_middleware'
44
- spec.add_runtime_dependency 'savon', '~> 2.0'
45
- end