certutil 0.1.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 +7 -0
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +53 -0
- data/LICENSE.txt +22 -0
- data/README.md +18 -0
- data/README.rdoc +19 -0
- data/Rakefile +61 -0
- data/bin/certutil +80 -0
- data/certutil.gemspec +27 -0
- data/features/certutil.feature +75 -0
- data/features/google-full.crt +120 -0
- data/features/google-short.crt +87 -0
- data/features/step_definitions/certdecoder_steps.rb +12 -0
- data/features/support/env.rb +16 -0
- data/lib/certutil.rb +6 -0
- data/lib/certutil/certificate_parser.rb +124 -0
- data/lib/certutil/version.rb +3 -0
- data/spec/certificate_parser_spec.rb +67 -0
- data/spec/spec_helper.rb +10 -0
- metadata +156 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 337ac9e815212f52c227e2b4d3ac7da2fda87640
|
4
|
+
data.tar.gz: 022b56ab7537b0a0e167d129ac07cc9a5cba9f75
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 99f5d062fa56b786613779a8d8d5b5dc8a9c8d8757c45316d2944367999327abc21ca87b1b6a7dc41695fa41727c2715b759f9ed1147d87762431e4809152995
|
7
|
+
data.tar.gz: 3f51c62de7017d20340ec87733eef9a92f16ea30f8ca1d1b9c610c986fc50d6217544a6160c5977b9ff3cdd221602dd759e6a8b285f075f739ddf3dd690805ba
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
certutil (0.1.0)
|
5
|
+
methadone (~> 1.3.2)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
aruba (0.5.4)
|
11
|
+
childprocess (>= 0.3.6)
|
12
|
+
cucumber (>= 1.1.1)
|
13
|
+
rspec-expectations (>= 2.7.0)
|
14
|
+
builder (3.2.2)
|
15
|
+
childprocess (0.5.1)
|
16
|
+
ffi (~> 1.0, >= 1.0.11)
|
17
|
+
cucumber (1.3.12)
|
18
|
+
builder (>= 2.1.2)
|
19
|
+
diff-lcs (>= 1.1.3)
|
20
|
+
gherkin (~> 2.12)
|
21
|
+
multi_json (>= 1.7.5, < 2.0)
|
22
|
+
multi_test (>= 0.1.1)
|
23
|
+
diff-lcs (1.2.5)
|
24
|
+
ffi (1.9.3)
|
25
|
+
gherkin (2.12.2)
|
26
|
+
multi_json (~> 1.3)
|
27
|
+
json (1.8.1)
|
28
|
+
methadone (1.3.2)
|
29
|
+
bundler
|
30
|
+
multi_json (1.9.2)
|
31
|
+
multi_test (0.1.1)
|
32
|
+
rake (0.9.6)
|
33
|
+
rdoc (4.1.1)
|
34
|
+
json (~> 1.4)
|
35
|
+
rspec (2.14.1)
|
36
|
+
rspec-core (~> 2.14.0)
|
37
|
+
rspec-expectations (~> 2.14.0)
|
38
|
+
rspec-mocks (~> 2.14.0)
|
39
|
+
rspec-core (2.14.8)
|
40
|
+
rspec-expectations (2.14.5)
|
41
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
42
|
+
rspec-mocks (2.14.6)
|
43
|
+
|
44
|
+
PLATFORMS
|
45
|
+
ruby
|
46
|
+
|
47
|
+
DEPENDENCIES
|
48
|
+
aruba
|
49
|
+
bundler (~> 1.5)
|
50
|
+
certutil!
|
51
|
+
rake (~> 0.9.2)
|
52
|
+
rdoc
|
53
|
+
rspec
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Chad Bailey
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Certutil
|
2
|
+
|
3
|
+
This is a tool I developed after dealing with a lot of SSL certificates in Heroku Support.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Just `gem install certutil` to install it.
|
8
|
+
|
9
|
+
`rbenv rehash` if you're using rbenv. You might have to do something to RVM to get it to show up there; honestly I can't remember.
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
This app uses locally saved certificate files (ones that look like `---BEGIN CERTIFICATE---`), or it can fetch them from a live site directly.
|
14
|
+
|
15
|
+
Just run `certutil file.crt` for a local file, or `certutil google.com` to get the cert from the web.
|
16
|
+
|
17
|
+
By default, the app parses the cert chain and displays a decoded version of the entire chain. See `certutil --help` for more options, or `rake features` to see some example use cases.
|
18
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= certutil - DESCRIBE YOUR GEM
|
2
|
+
|
3
|
+
Author:: YOUR NAME (YOUR EMAIL)
|
4
|
+
Copyright:: Copyright (c) 2014 YOUR NAME
|
5
|
+
|
6
|
+
|
7
|
+
DESCRIBE YOUR GEM HERE
|
8
|
+
|
9
|
+
== Links
|
10
|
+
|
11
|
+
* {Source on Github}[LINK TO GITHUB]
|
12
|
+
* RDoc[LINK TO RDOC.INFO]
|
13
|
+
|
14
|
+
== Install
|
15
|
+
|
16
|
+
== Examples
|
17
|
+
|
18
|
+
== Contributing
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
|
3
|
+
RSpec::Core::RakeTask.new('spec')
|
4
|
+
|
5
|
+
def dump_load_path
|
6
|
+
puts $LOAD_PATH.join("\n")
|
7
|
+
found = nil
|
8
|
+
$LOAD_PATH.each do |path|
|
9
|
+
if File.exists?(File.join(path,"rspec"))
|
10
|
+
puts "Found rspec in #{path}"
|
11
|
+
if File.exists?(File.join(path,"rspec","core"))
|
12
|
+
puts "Found core"
|
13
|
+
if File.exists?(File.join(path,"rspec","core","rake_task"))
|
14
|
+
puts "Found rake_task"
|
15
|
+
found = path
|
16
|
+
else
|
17
|
+
puts "!! no rake_task"
|
18
|
+
end
|
19
|
+
else
|
20
|
+
puts "!!! no core"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
if found.nil?
|
25
|
+
puts "Didn't find rspec/core/rake_task anywhere"
|
26
|
+
else
|
27
|
+
puts "Found in #{path}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
require 'bundler'
|
31
|
+
require 'rake/clean'
|
32
|
+
|
33
|
+
require 'rake/testtask'
|
34
|
+
|
35
|
+
require 'cucumber'
|
36
|
+
require 'cucumber/rake/task'
|
37
|
+
gem 'rdoc' # we need the installed RDoc gem, not the system one
|
38
|
+
require 'rdoc/task'
|
39
|
+
|
40
|
+
include Rake::DSL
|
41
|
+
|
42
|
+
Bundler::GemHelper.install_tasks
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
CUKE_RESULTS = 'results.html'
|
47
|
+
CLEAN << CUKE_RESULTS
|
48
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
49
|
+
t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty --no-source -x"
|
50
|
+
t.fork = false
|
51
|
+
end
|
52
|
+
|
53
|
+
Rake::RDocTask.new do |rd|
|
54
|
+
|
55
|
+
rd.main = "README.rdoc"
|
56
|
+
|
57
|
+
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
58
|
+
end
|
59
|
+
|
60
|
+
task :default => [:spec,:features]
|
61
|
+
|
data/bin/certutil
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'methadone'
|
5
|
+
require 'certutil.rb'
|
6
|
+
|
7
|
+
class App
|
8
|
+
include Methadone::Main
|
9
|
+
include Methadone::CLILogging
|
10
|
+
|
11
|
+
main do |source| # Add args you want: |like,so|
|
12
|
+
# your program code here
|
13
|
+
# You can access CLI options via
|
14
|
+
# the options Hash
|
15
|
+
|
16
|
+
debug "from bin, wd is #{Dir.pwd}"
|
17
|
+
|
18
|
+
@cp = CertificateParser.new_from_input(source)
|
19
|
+
#if options["input"]
|
20
|
+
#@cp = CertificateParser.new_from_file(File.expand_path(options["input"]))
|
21
|
+
#elsif options["hostname"]
|
22
|
+
#@cp = CertificateParser.new_from_hostname(options["hostname"])
|
23
|
+
#else
|
24
|
+
#error "You must include a cert file with -i or a hostname with -h."
|
25
|
+
#end
|
26
|
+
|
27
|
+
if @cp.certs.count == 0
|
28
|
+
error "!! Couldn't find any valid certificates. Make sure your input contains -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- blocks."
|
29
|
+
elsif @cp.certs.count == 1
|
30
|
+
info "Found 1 certificate."
|
31
|
+
else
|
32
|
+
info "Found #{@cp.certs.count} certificates."
|
33
|
+
end
|
34
|
+
|
35
|
+
if options[:split]
|
36
|
+
@cp.write_crt_files! if options[:output] == "crt"
|
37
|
+
@cp.write_txt_files! if options[:output] == "txt"
|
38
|
+
else
|
39
|
+
@cp.write_crt_file! if options[:output] == "crt"
|
40
|
+
@cp.write_txt_file! if options[:output] == "txt"
|
41
|
+
end
|
42
|
+
|
43
|
+
info @cp.decoded.join("\n-----\n\n") unless options[:mute]
|
44
|
+
end
|
45
|
+
|
46
|
+
# supplemental methods here
|
47
|
+
|
48
|
+
# Declare command-line interface here
|
49
|
+
|
50
|
+
# description "one line description of your app"
|
51
|
+
#
|
52
|
+
# Accept flags via:
|
53
|
+
# on("--flag VAL","Some flag")
|
54
|
+
#on("--input FILE", "-i FILE", "Input .crt/.pem file")
|
55
|
+
#on("--hostname HOSTNAME", "-h HOSTNAME", "Hostname from which to fetch certificate")
|
56
|
+
on("--output FORMAT", "-o", "Write out results to the current directory (formats are crt or txt (decoded)")
|
57
|
+
on("--split", "-s", "Split multiple certs into separate files for writing")
|
58
|
+
on("--mute", "-m", "Mute output")
|
59
|
+
|
60
|
+
# options[flag] will contain VAL
|
61
|
+
#
|
62
|
+
# Specify switches via:
|
63
|
+
# on("--[no-]switch","Some switch")
|
64
|
+
arg :source, "The cert(s) on which to operate (filename, hostname or gist link)"
|
65
|
+
|
66
|
+
#
|
67
|
+
# Or, just call OptionParser methods on opts
|
68
|
+
#
|
69
|
+
# Require an argument
|
70
|
+
# arg :some_arg
|
71
|
+
#
|
72
|
+
# # Make an argument optional
|
73
|
+
# arg :optional_arg, :optional
|
74
|
+
|
75
|
+
version Certutil::VERSION
|
76
|
+
|
77
|
+
use_log_level_option
|
78
|
+
|
79
|
+
go!
|
80
|
+
end
|
data/certutil.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'certutil/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "certutil"
|
8
|
+
spec.version = Certutil::VERSION
|
9
|
+
spec.authors = ["Chad Bailey"]
|
10
|
+
spec.email = ["chad@heroku.com"]
|
11
|
+
spec.summary = %q{A tool for decoding and analyzing SSL certificates.}
|
12
|
+
spec.description = %q{A tool for decoding and analyzing SSL certificates.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rspec"
|
23
|
+
spec.add_development_dependency('rdoc')
|
24
|
+
spec.add_development_dependency('aruba')
|
25
|
+
spec.add_development_dependency('rake', '~> 0.9.2')
|
26
|
+
spec.add_dependency('methadone', '~> 1.3.2')
|
27
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
Feature: My bootstrapped app kinda works
|
2
|
+
In order to get going on coding my awesome app
|
3
|
+
I want to have aruba and cucumber setup
|
4
|
+
So I don't have to do it myself
|
5
|
+
|
6
|
+
Scenario: App just runs
|
7
|
+
When I get help for "certutil"
|
8
|
+
Then the exit status should be 0
|
9
|
+
And the banner should be present
|
10
|
+
And the banner should document that this app takes options
|
11
|
+
And the following options should be documented:
|
12
|
+
|--version|
|
13
|
+
|--output|
|
14
|
+
|--split|
|
15
|
+
|--mute|
|
16
|
+
And the banner should document that this app's arguments are:
|
17
|
+
|source|which is required|
|
18
|
+
|
19
|
+
Scenario: Parse full file
|
20
|
+
When I run `certutil ../../features/google-full.crt --log-level debug`
|
21
|
+
Then the output should contain "google-full"
|
22
|
+
And the output should contain "Found 3 certificates."
|
23
|
+
And the output should contain "Google Internet Authority"
|
24
|
+
|
25
|
+
Scenario: Parse abbreviated file
|
26
|
+
When I run `certutil ../../features/google-short.crt`
|
27
|
+
Then the output should contain "google-short"
|
28
|
+
And the output should contain "Found 3 certificates."
|
29
|
+
And the output should contain "Google Internet Authority"
|
30
|
+
|
31
|
+
Scenario: Silent mode (mute)
|
32
|
+
When I run `certutil ../../features/google-short.crt -m`
|
33
|
+
Then the output should contain "google-short"
|
34
|
+
And the output should contain "Found 3 certificates."
|
35
|
+
And the output should not contain "Google Internet Authority"
|
36
|
+
|
37
|
+
Scenario: Parse URL
|
38
|
+
When I run `certutil google.com`
|
39
|
+
Then the output should contain "google.com"
|
40
|
+
And the output should contain "Found 3 certificates."
|
41
|
+
And the output should contain "Google Internet Authority"
|
42
|
+
|
43
|
+
Scenario: No cert
|
44
|
+
When I run `certutil`
|
45
|
+
Then the output should contain "parse error: 'source' is required"
|
46
|
+
|
47
|
+
|
48
|
+
Scenario: Write split CRT files
|
49
|
+
When I run `certutil ../../features/google-full.crt -s -o crt`
|
50
|
+
Then the output should contain "google-full"
|
51
|
+
And a file named "google-full-0.crt" should exist in my current directory
|
52
|
+
And a file named "google-full-1.crt" should exist in my current directory
|
53
|
+
And a file named "google-full-2.crt" should exist in my current directory
|
54
|
+
And the file named "google-full-0.crt" should contain "MIIHPzCCBiegAwIBAgII"
|
55
|
+
|
56
|
+
|
57
|
+
Scenario: Write split TXT files
|
58
|
+
When I run `certutil ../../features/google-full.crt -s -o txt`
|
59
|
+
Then the output should contain "google-full"
|
60
|
+
And a file named "google-full-0-decoded.txt" should exist in my current directory
|
61
|
+
And a file named "google-full-1-decoded.txt" should exist in my current directory
|
62
|
+
And a file named "google-full-2-decoded.txt" should exist in my current directory
|
63
|
+
And the file named "google-full-0-decoded.txt" should contain "Google Internet Authority"
|
64
|
+
|
65
|
+
Scenario: Write a single CRT file
|
66
|
+
When I run `certutil google.com --log-level debug -o crt`
|
67
|
+
Then the output should contain "google.com"
|
68
|
+
And a file named "google.com.crt" should exist in my current directory
|
69
|
+
And the file named "google.com.crt" should contain "MIIHPzCCBiegAwIBAgII"
|
70
|
+
|
71
|
+
Scenario: Write a single TXT file
|
72
|
+
When I run `certutil google.com -o txt`
|
73
|
+
Then the output should contain "google.com"
|
74
|
+
And a file named "google.com-decoded.txt" should exist in my current directory
|
75
|
+
And the file named "google.com-decoded.txt" should contain "Google Internet Authority"
|
@@ -0,0 +1,120 @@
|
|
1
|
+
CONNECTED(00000003)
|
2
|
+
---
|
3
|
+
Certificate chain
|
4
|
+
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
|
5
|
+
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
|
6
|
+
-----BEGIN CERTIFICATE-----
|
7
|
+
MIIHPzCCBiegAwIBAgIIXg768qmYVL0wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
|
8
|
+
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
|
9
|
+
cm5ldCBBdXRob3JpdHkgRzIwHhcNMTQwMzEyMDk1MzQwWhcNMTQwNjEwMDAwMDAw
|
10
|
+
WjBmMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
|
11
|
+
TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEVMBMGA1UEAwwMKi5n
|
12
|
+
b29nbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkDR4dXYy
|
13
|
+
+W5fPMG03Tuhsj0lVJKRKob7rUC4yuIeoPuNaEvBzD6nB6OVbBFZfAPpHAvphTw0
|
14
|
+
SWZXHEO2CSTtz7gz1S3pIqeMyJC04xd/oWuokT/NpGjeQAkAidTkeedPNu9Ix5EL
|
15
|
+
RVKGAQhxXuABth8uvoMrzT5Kx/mrq+YC4kxFevwfaePW88JO+rmb/VVeqmGnzgqU
|
16
|
+
dJV/B2euk2X0LX+lzcYw2xgIIBEICI0w3EJNBLzT7WIHbVjK/35owB6f9ni39wsu
|
17
|
+
xwCq1J9zTxcgbuSOg3REYtKHxHsMdwIHiuDa80s1Xc1TcMTKsp/aPjAWR/zEiIdB
|
18
|
+
niAZhJB2Tmp9FwIDAQABo4IEDDCCBAgwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
|
19
|
+
AQUFBwMCMIIC4gYDVR0RBIIC2TCCAtWCDCouZ29vZ2xlLmNvbYINKi5hbmRyb2lk
|
20
|
+
LmNvbYIWKi5hcHBlbmdpbmUuZ29vZ2xlLmNvbYISKi5jbG91ZC5nb29nbGUuY29t
|
21
|
+
ghYqLmdvb2dsZS1hbmFseXRpY3MuY29tggsqLmdvb2dsZS5jYYILKi5nb29nbGUu
|
22
|
+
Y2yCDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qcIIOKi5nb29nbGUuY28u
|
23
|
+
dWuCDyouZ29vZ2xlLmNvbS5hcoIPKi5nb29nbGUuY29tLmF1gg8qLmdvb2dsZS5j
|
24
|
+
b20uYnKCDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLm14gg8qLmdvb2ds
|
25
|
+
ZS5jb20udHKCDyouZ29vZ2xlLmNvbS52boILKi5nb29nbGUuZGWCCyouZ29vZ2xl
|
26
|
+
LmVzggsqLmdvb2dsZS5mcoILKi5nb29nbGUuaHWCCyouZ29vZ2xlLml0ggsqLmdv
|
27
|
+
b2dsZS5ubIILKi5nb29nbGUucGyCCyouZ29vZ2xlLnB0gg8qLmdvb2dsZWFwaXMu
|
28
|
+
Y26CFCouZ29vZ2xlY29tbWVyY2UuY29tghEqLmdvb2dsZXZpZGVvLmNvbYINKi5n
|
29
|
+
c3RhdGljLmNvbYIKKi5ndnQxLmNvbYIMKi51cmNoaW4uY29tghAqLnVybC5nb29n
|
30
|
+
bGUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tgg0qLnlvdXR1YmUuY29tghYq
|
31
|
+
LnlvdXR1YmVlZHVjYXRpb24uY29tggsqLnl0aW1nLmNvbYILYW5kcm9pZC5jb22C
|
32
|
+
BGcuY2+CBmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5jb22CCmdvb2dsZS5jb22C
|
33
|
+
Emdvb2dsZWNvbW1lcmNlLmNvbYIKdXJjaGluLmNvbYIIeW91dHUuYmWCC3lvdXR1
|
34
|
+
YmUuY29tghR5b3V0dWJlZWR1Y2F0aW9uLmNvbTBoBggrBgEFBQcBAQRcMFowKwYI
|
35
|
+
KwYBBQUHMAKGH2h0dHA6Ly9wa2kuZ29vZ2xlLmNvbS9HSUFHMi5jcnQwKwYIKwYB
|
36
|
+
BQUHMAGGH2h0dHA6Ly9jbGllbnRzMS5nb29nbGUuY29tL29jc3AwHQYDVR0OBBYE
|
37
|
+
FGdKaoHIMQ7lHCrxueGq7sgmqowwMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU
|
38
|
+
St0GFhu89mi1dvWBtrtiGrpagS8wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMDAG
|
39
|
+
A1UdHwQpMCcwJaAjoCGGH2h0dHA6Ly9wa2kuZ29vZ2xlLmNvbS9HSUFHMi5jcmww
|
40
|
+
DQYJKoZIhvcNAQEFBQADggEBAES1P4XqtSjXyGCuEw0CBJpDSdUCpF/t0hEMPd4+
|
41
|
+
VpJPrVlhUkcTRiLUi9PtneA6qkqbkFNtB3rj0TsoEq2AsMfw576zS8YSDYcXqDzX
|
42
|
+
S1VsXykK2YnlVapMGXVVZFeXxCSCpb1fMknE/3Y80St5Pyj+Gtl8m2wRmdGX6Hw/
|
43
|
+
6GSs1WsSq0dn7w1nqZKIm9FSlzofCPOyhMpM8GyrygqyBKoQcl0nJbnEiNzQAOum
|
44
|
+
YlOlLCmXhf3LyxUhjcaYMulPiXrzsdCikVotfAhPF0BDCDF8/6SQ2y0RYw1NionU
|
45
|
+
G6VANTpbplIlpqm+47cjO7VZv55GfZ3hJswfrdrWKIm/1mA=
|
46
|
+
-----END CERTIFICATE-----
|
47
|
+
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
|
48
|
+
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
|
49
|
+
-----BEGIN CERTIFICATE-----
|
50
|
+
MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
|
51
|
+
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
|
52
|
+
YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG
|
53
|
+
EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
|
54
|
+
bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
55
|
+
AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
|
56
|
+
VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
|
57
|
+
h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
|
58
|
+
ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
|
59
|
+
EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
|
60
|
+
DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7
|
61
|
+
qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD
|
62
|
+
VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g
|
63
|
+
K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI
|
64
|
+
KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n
|
65
|
+
ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB
|
66
|
+
BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY
|
67
|
+
/iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/
|
68
|
+
zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza
|
69
|
+
HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto
|
70
|
+
WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6
|
71
|
+
yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx
|
72
|
+
-----END CERTIFICATE-----
|
73
|
+
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
|
74
|
+
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
|
75
|
+
-----BEGIN CERTIFICATE-----
|
76
|
+
MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
|
77
|
+
MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
|
78
|
+
aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
|
79
|
+
WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
|
80
|
+
AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
81
|
+
CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
|
82
|
+
OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
|
83
|
+
T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
|
84
|
+
JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
|
85
|
+
Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
|
86
|
+
PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
|
87
|
+
aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
|
88
|
+
TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
|
89
|
+
LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
|
90
|
+
BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
|
91
|
+
dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
|
92
|
+
AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
|
93
|
+
NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
|
94
|
+
b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
|
95
|
+
-----END CERTIFICATE-----
|
96
|
+
---
|
97
|
+
Server certificate
|
98
|
+
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
|
99
|
+
issuer=/C=US/O=Google Inc/CN=Google Internet Authority G2
|
100
|
+
---
|
101
|
+
No client certificate CA names sent
|
102
|
+
---
|
103
|
+
SSL handshake has read 3951 bytes and written 444 bytes
|
104
|
+
---
|
105
|
+
New, TLSv1/SSLv3, Cipher is RC4-SHA
|
106
|
+
Server public key is 2048 bit
|
107
|
+
Secure Renegotiation IS supported
|
108
|
+
Compression: NONE
|
109
|
+
Expansion: NONE
|
110
|
+
SSL-Session:
|
111
|
+
Protocol : TLSv1
|
112
|
+
Cipher : RC4-SHA
|
113
|
+
Session-ID: 188ED57889943028AEC5FA0251A329DD1EFB203C74A204916ABF23D8C2D5446F
|
114
|
+
Session-ID-ctx:
|
115
|
+
Master-Key: 4F2518953BAADC2221CF08C4BD49B75096820BA7DBD2F002041DEC72EEAFDC73DC684D5FEE509563E80D8126430346A2
|
116
|
+
Key-Arg : None
|
117
|
+
Start Time: 1395678805
|
118
|
+
Timeout : 300 (sec)
|
119
|
+
Verify return code: 0 (ok)
|
120
|
+
---
|
@@ -0,0 +1,87 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIHPzCCBiegAwIBAgIIXg768qmYVL0wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
|
3
|
+
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
|
4
|
+
cm5ldCBBdXRob3JpdHkgRzIwHhcNMTQwMzEyMDk1MzQwWhcNMTQwNjEwMDAwMDAw
|
5
|
+
WjBmMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
|
6
|
+
TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEVMBMGA1UEAwwMKi5n
|
7
|
+
b29nbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkDR4dXYy
|
8
|
+
+W5fPMG03Tuhsj0lVJKRKob7rUC4yuIeoPuNaEvBzD6nB6OVbBFZfAPpHAvphTw0
|
9
|
+
SWZXHEO2CSTtz7gz1S3pIqeMyJC04xd/oWuokT/NpGjeQAkAidTkeedPNu9Ix5EL
|
10
|
+
RVKGAQhxXuABth8uvoMrzT5Kx/mrq+YC4kxFevwfaePW88JO+rmb/VVeqmGnzgqU
|
11
|
+
dJV/B2euk2X0LX+lzcYw2xgIIBEICI0w3EJNBLzT7WIHbVjK/35owB6f9ni39wsu
|
12
|
+
xwCq1J9zTxcgbuSOg3REYtKHxHsMdwIHiuDa80s1Xc1TcMTKsp/aPjAWR/zEiIdB
|
13
|
+
niAZhJB2Tmp9FwIDAQABo4IEDDCCBAgwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
|
14
|
+
AQUFBwMCMIIC4gYDVR0RBIIC2TCCAtWCDCouZ29vZ2xlLmNvbYINKi5hbmRyb2lk
|
15
|
+
LmNvbYIWKi5hcHBlbmdpbmUuZ29vZ2xlLmNvbYISKi5jbG91ZC5nb29nbGUuY29t
|
16
|
+
ghYqLmdvb2dsZS1hbmFseXRpY3MuY29tggsqLmdvb2dsZS5jYYILKi5nb29nbGUu
|
17
|
+
Y2yCDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qcIIOKi5nb29nbGUuY28u
|
18
|
+
dWuCDyouZ29vZ2xlLmNvbS5hcoIPKi5nb29nbGUuY29tLmF1gg8qLmdvb2dsZS5j
|
19
|
+
b20uYnKCDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLm14gg8qLmdvb2ds
|
20
|
+
ZS5jb20udHKCDyouZ29vZ2xlLmNvbS52boILKi5nb29nbGUuZGWCCyouZ29vZ2xl
|
21
|
+
LmVzggsqLmdvb2dsZS5mcoILKi5nb29nbGUuaHWCCyouZ29vZ2xlLml0ggsqLmdv
|
22
|
+
b2dsZS5ubIILKi5nb29nbGUucGyCCyouZ29vZ2xlLnB0gg8qLmdvb2dsZWFwaXMu
|
23
|
+
Y26CFCouZ29vZ2xlY29tbWVyY2UuY29tghEqLmdvb2dsZXZpZGVvLmNvbYINKi5n
|
24
|
+
c3RhdGljLmNvbYIKKi5ndnQxLmNvbYIMKi51cmNoaW4uY29tghAqLnVybC5nb29n
|
25
|
+
bGUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tgg0qLnlvdXR1YmUuY29tghYq
|
26
|
+
LnlvdXR1YmVlZHVjYXRpb24uY29tggsqLnl0aW1nLmNvbYILYW5kcm9pZC5jb22C
|
27
|
+
BGcuY2+CBmdvby5nbIIUZ29vZ2xlLWFuYWx5dGljcy5jb22CCmdvb2dsZS5jb22C
|
28
|
+
Emdvb2dsZWNvbW1lcmNlLmNvbYIKdXJjaGluLmNvbYIIeW91dHUuYmWCC3lvdXR1
|
29
|
+
YmUuY29tghR5b3V0dWJlZWR1Y2F0aW9uLmNvbTBoBggrBgEFBQcBAQRcMFowKwYI
|
30
|
+
KwYBBQUHMAKGH2h0dHA6Ly9wa2kuZ29vZ2xlLmNvbS9HSUFHMi5jcnQwKwYIKwYB
|
31
|
+
BQUHMAGGH2h0dHA6Ly9jbGllbnRzMS5nb29nbGUuY29tL29jc3AwHQYDVR0OBBYE
|
32
|
+
FGdKaoHIMQ7lHCrxueGq7sgmqowwMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU
|
33
|
+
St0GFhu89mi1dvWBtrtiGrpagS8wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMDAG
|
34
|
+
A1UdHwQpMCcwJaAjoCGGH2h0dHA6Ly9wa2kuZ29vZ2xlLmNvbS9HSUFHMi5jcmww
|
35
|
+
DQYJKoZIhvcNAQEFBQADggEBAES1P4XqtSjXyGCuEw0CBJpDSdUCpF/t0hEMPd4+
|
36
|
+
VpJPrVlhUkcTRiLUi9PtneA6qkqbkFNtB3rj0TsoEq2AsMfw576zS8YSDYcXqDzX
|
37
|
+
S1VsXykK2YnlVapMGXVVZFeXxCSCpb1fMknE/3Y80St5Pyj+Gtl8m2wRmdGX6Hw/
|
38
|
+
6GSs1WsSq0dn7w1nqZKIm9FSlzofCPOyhMpM8GyrygqyBKoQcl0nJbnEiNzQAOum
|
39
|
+
YlOlLCmXhf3LyxUhjcaYMulPiXrzsdCikVotfAhPF0BDCDF8/6SQ2y0RYw1NionU
|
40
|
+
G6VANTpbplIlpqm+47cjO7VZv55GfZ3hJswfrdrWKIm/1mA=
|
41
|
+
-----END CERTIFICATE-----
|
42
|
+
-----BEGIN CERTIFICATE-----
|
43
|
+
MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
|
44
|
+
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
|
45
|
+
YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG
|
46
|
+
EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
|
47
|
+
bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
48
|
+
AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
|
49
|
+
VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
|
50
|
+
h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
|
51
|
+
ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
|
52
|
+
EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
|
53
|
+
DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7
|
54
|
+
qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD
|
55
|
+
VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g
|
56
|
+
K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI
|
57
|
+
KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n
|
58
|
+
ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB
|
59
|
+
BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY
|
60
|
+
/iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/
|
61
|
+
zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza
|
62
|
+
HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto
|
63
|
+
WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6
|
64
|
+
yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx
|
65
|
+
-----END CERTIFICATE-----
|
66
|
+
-----BEGIN CERTIFICATE-----
|
67
|
+
MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
|
68
|
+
MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
|
69
|
+
aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
|
70
|
+
WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
|
71
|
+
AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
72
|
+
CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
|
73
|
+
OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
|
74
|
+
T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
|
75
|
+
JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
|
76
|
+
Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
|
77
|
+
PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
|
78
|
+
aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
|
79
|
+
TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
|
80
|
+
LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
|
81
|
+
BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
|
82
|
+
dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
|
83
|
+
AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
|
84
|
+
NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
|
85
|
+
b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
|
86
|
+
-----END CERTIFICATE-----
|
87
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Put your step definitions here
|
2
|
+
Then(/^a file named "(.*?)" should exist in my current directory$/) do |filename|
|
3
|
+
# Aruba cd's to tmp/aruba before it runs things, ugh
|
4
|
+
path = File.join(Dir.pwd, "tmp", "aruba", filename)
|
5
|
+
expect(File.exist?(path)).to be_true
|
6
|
+
end
|
7
|
+
|
8
|
+
Then(/^the file named "(.*?)" should contain "(.*?)"$/) do |filename, content|
|
9
|
+
# Aruba cd's to tmp/aruba before it runs things, ugh
|
10
|
+
path = File.join(Dir.pwd, "tmp", "aruba", filename)
|
11
|
+
expect(File.read(path)).to include(content)
|
12
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'aruba/cucumber'
|
2
|
+
require 'methadone/cucumber'
|
3
|
+
|
4
|
+
ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
5
|
+
LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
|
6
|
+
|
7
|
+
Before do
|
8
|
+
# Using "announce" causes massive warnings on 1.9.2
|
9
|
+
@puts = true
|
10
|
+
@original_rubylib = ENV['RUBYLIB']
|
11
|
+
ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
After do
|
15
|
+
ENV['RUBYLIB'] = @original_rubylib
|
16
|
+
end
|
data/lib/certutil.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
class CertificateParser
|
4
|
+
include Methadone::CLILogging
|
5
|
+
include Methadone::SH
|
6
|
+
|
7
|
+
|
8
|
+
def self.new_from_input(input)
|
9
|
+
new_from_file(File.expand_path(input)) || new_from_hostname(input)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.new_from_file(path)
|
13
|
+
# should return nil if it's not a valid cert
|
14
|
+
|
15
|
+
debug "Parsing #{path}..."
|
16
|
+
begin
|
17
|
+
string = File.read(path)
|
18
|
+
if string
|
19
|
+
path_array = path.split(File::SEPARATOR)
|
20
|
+
debug "Creating..."
|
21
|
+
self.new(string: string, name: path_array.last.gsub(/(\.crt)|(.pem)/, ""), source: :file)
|
22
|
+
end
|
23
|
+
rescue
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.new_from_hostname(hostname)
|
29
|
+
debug "Fetching certificate from #{hostname}..."
|
30
|
+
debug "Creating..."
|
31
|
+
string = `openssl s_client -connect #{hostname}:443 -showcerts </dev/null`
|
32
|
+
self.new(string: string, name: hostname, source: :hostname) unless string == ""
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.new_from_gist(gist_link)
|
36
|
+
# not yet
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.new_from_string(string, opts = {})
|
40
|
+
self.new(string: string, name: (opts[:name] || "temp"))
|
41
|
+
end
|
42
|
+
|
43
|
+
def certs
|
44
|
+
@certs ||= split_input
|
45
|
+
end
|
46
|
+
|
47
|
+
def decoded
|
48
|
+
debug "lazy loading decoded..."
|
49
|
+
@decoded ||= decode
|
50
|
+
debug "lazy loading done."
|
51
|
+
|
52
|
+
@decoded
|
53
|
+
end
|
54
|
+
|
55
|
+
def initialize(attrs = {})
|
56
|
+
@input = attrs[:string]
|
57
|
+
@name = attrs[:name]
|
58
|
+
@path = Dir.pwd
|
59
|
+
info "Certificate loaded#{' from ' + attrs[:source].to_s if attrs[:source]}: #{@name}."
|
60
|
+
end
|
61
|
+
|
62
|
+
def write_crt_files!
|
63
|
+
info "Writing separate .crt files..."
|
64
|
+
certs.each_with_index do |cert, i|
|
65
|
+
debug "right now, wd is #{Dir.pwd}"
|
66
|
+
File.open(File.join(@path, "#{@name}-#{i}.crt"), "w") { |f| f.write(cert) }
|
67
|
+
debug "--> Wrote #{@path} -- #{@name}-#{i}.crt."
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def write_crt_file!
|
72
|
+
info "Writing .crt file..."
|
73
|
+
joined = certs.join("\n") + "\n"
|
74
|
+
File.open(File.join(@path, "#{@name}.crt"), "w") { |f| f.write(joined) }
|
75
|
+
debug "--> Wrote #{@path} -- #{@name}.crt."
|
76
|
+
end
|
77
|
+
|
78
|
+
def write_txt_files!
|
79
|
+
info "Writing separate .txt files..."
|
80
|
+
decoded.each_with_index do |cert, i|
|
81
|
+
File.open(File.join(@path, "#{@name}-#{i}-decoded.txt"), "w") { |f| f.write(cert) }
|
82
|
+
debug "--> Wrote #{@path}/#{@name}-#{i}-decoded.txt."
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def write_txt_file!
|
87
|
+
info "Writing .txt file..."
|
88
|
+
joined = decoded.join("\n-----\n") + "\n"
|
89
|
+
File.open(File.join(@path, "#{@name}-decoded.txt"), "w") { |f| f.write(joined) }
|
90
|
+
debug "--> Wrote #{@path}/#{@name}-decoded.txt."
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def split_input
|
96
|
+
debug "splitting..."
|
97
|
+
matches = @input.scan(/-+BEGIN CERTIFICATE-----.*?-+END CERTIFICATE-+/m)
|
98
|
+
matches = matches.map do |cert|
|
99
|
+
# cert.gsub!(/-----BEGIN CERTIFICATE-----\n?/, "")
|
100
|
+
# cert.gsub!(/-----END CERTIFICATE-----\n?/, "")
|
101
|
+
# cert.chomp
|
102
|
+
cert
|
103
|
+
end
|
104
|
+
|
105
|
+
debug "Found #{matches.count} matches."
|
106
|
+
matches
|
107
|
+
end
|
108
|
+
|
109
|
+
def decode
|
110
|
+
debug "Decoding..."
|
111
|
+
output = self.certs.map do |cert|
|
112
|
+
Open3.popen3("openssl x509 -text -noout") do |stdin, stdout, stderr|
|
113
|
+
stdin.write(cert)
|
114
|
+
stdin.close_write
|
115
|
+
out = stdout.read
|
116
|
+
debug "stdout: #{out}"
|
117
|
+
out
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
debug "decode output is #{output}."
|
122
|
+
output
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CertificateParser do
|
4
|
+
before :all do
|
5
|
+
@string_data = <<-doc
|
6
|
+
-----BEGIN CERTIFICATE-----
|
7
|
+
abcdef
|
8
|
+
-----END CERTIFICATE-----
|
9
|
+
-----BEGIN CERTIFICATE-----
|
10
|
+
123456
|
11
|
+
-----END CERTIFICATE-----
|
12
|
+
doc
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ".new_from_hostname" do
|
16
|
+
it "creates a CertificateParser from a valid file" do
|
17
|
+
@cp = CertificateParser.new_from_file(File.join(Dir.pwd, "features/google-full.crt"))
|
18
|
+
expect(@cp).to be_a CertificateParser
|
19
|
+
expect(@cp.certs).to be_a Array
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns nil if the file doesn't exist" do
|
23
|
+
@cp = CertificateParser.new_from_file(File.join(Dir.pwd, "nil.crt"))
|
24
|
+
expect(@cp).to be_nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe ".new_from_file" do
|
29
|
+
it "creates a CertificateParser from a valid hostname" do
|
30
|
+
@cp = CertificateParser.new_from_hostname("google.com")
|
31
|
+
expect(@cp).to be_a CertificateParser
|
32
|
+
expect(@cp.certs).to be_a Array
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns nil if it can't find a certificate" do
|
36
|
+
@cp = CertificateParser.new_from_hostname("fake.domain")
|
37
|
+
expect(@cp).to be_nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe ".new_from_input" do
|
42
|
+
it "creates a CertificateParser from hostname" do
|
43
|
+
expect(CertificateParser.new_from_hostname("google.com")).to be_a CertificateParser
|
44
|
+
end
|
45
|
+
|
46
|
+
it "creates a CertificateParser from a file" do
|
47
|
+
expect(CertificateParser.new_from_file(File.join(Dir.pwd, "features/google-full.crt"))).to be_a CertificateParser
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#certs" do
|
52
|
+
it "splits a cert string into an array" do
|
53
|
+
@cp = CertificateParser.new_from_string(@string_data)
|
54
|
+
expect(@cp.certs.count).to eq(2)
|
55
|
+
expect(@cp.certs[0]).to include("abcdef")
|
56
|
+
expect(@cp.certs[1]).to include("123456")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "decoded" do
|
61
|
+
it "decodes certificates" do
|
62
|
+
@cp = CertificateParser.new_from_file("features/google-full.crt")
|
63
|
+
@cp.decoded.first.should include("Google")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'methadone'
|
3
|
+
Bundler.setup
|
4
|
+
|
5
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
6
|
+
require File.join(APP_ROOT, 'lib/certutil') # so rspec knows where your file could be
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
# some (optional) config here
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: certutil
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chad Bailey
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rdoc
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: aruba
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.9.2
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.9.2
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: methadone
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.3.2
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.3.2
|
97
|
+
description: A tool for decoding and analyzing SSL certificates.
|
98
|
+
email:
|
99
|
+
- chad@heroku.com
|
100
|
+
executables:
|
101
|
+
- certutil
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".rspec"
|
107
|
+
- Gemfile
|
108
|
+
- Gemfile.lock
|
109
|
+
- LICENSE.txt
|
110
|
+
- README.md
|
111
|
+
- README.rdoc
|
112
|
+
- Rakefile
|
113
|
+
- bin/certutil
|
114
|
+
- certutil.gemspec
|
115
|
+
- features/certutil.feature
|
116
|
+
- features/google-full.crt
|
117
|
+
- features/google-short.crt
|
118
|
+
- features/step_definitions/certdecoder_steps.rb
|
119
|
+
- features/support/env.rb
|
120
|
+
- lib/certutil.rb
|
121
|
+
- lib/certutil/certificate_parser.rb
|
122
|
+
- lib/certutil/version.rb
|
123
|
+
- spec/certificate_parser_spec.rb
|
124
|
+
- spec/spec_helper.rb
|
125
|
+
homepage: ''
|
126
|
+
licenses:
|
127
|
+
- MIT
|
128
|
+
metadata: {}
|
129
|
+
post_install_message:
|
130
|
+
rdoc_options: []
|
131
|
+
require_paths:
|
132
|
+
- lib
|
133
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
requirements: []
|
144
|
+
rubyforge_project:
|
145
|
+
rubygems_version: 2.2.2
|
146
|
+
signing_key:
|
147
|
+
specification_version: 4
|
148
|
+
summary: A tool for decoding and analyzing SSL certificates.
|
149
|
+
test_files:
|
150
|
+
- features/certutil.feature
|
151
|
+
- features/google-full.crt
|
152
|
+
- features/google-short.crt
|
153
|
+
- features/step_definitions/certdecoder_steps.rb
|
154
|
+
- features/support/env.rb
|
155
|
+
- spec/certificate_parser_spec.rb
|
156
|
+
- spec/spec_helper.rb
|