mkchain 1.0.2
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/README.md +43 -0
- data/bin/mkchain +11 -0
- data/lib/mkchain.rb +24 -0
- data/mkchain.gemspec +23 -0
- metadata +48 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8aae86e806bc9471db4e2a5994286ac337b87adf
|
4
|
+
data.tar.gz: b68eb7c03ebd4eaaef510b797560c892f63b6d4a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dc1decc59607d9ed117a273eb60efdeab5b007669eba5a8cbc4e0c1d6497edf9f6c1f7e3916b19da9b8fad4b5d4dc0dab93af3ecf58baff8a0d69e154d61d2fc
|
7
|
+
data.tar.gz: 53e725b7dbad4eeb0c4c76d4da9c28a68455f6955457d306a1dcfe8e9360472ea3fb2a987fc6a7e4398c2355e76fb4b79389f9ce91a67917a113963180960190
|
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# mkchain
|
2
|
+
|
3
|
+
Given a certificate filename as input, `mkchain` will attempt to build the
|
4
|
+
intermediate certificate chain, and print it to stdout. This replaces the
|
5
|
+
need to copy/edit cert-vendor provided chain files and deal with certificate
|
6
|
+
order.
|
7
|
+
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
$ rake install
|
12
|
+
|
13
|
+
|
14
|
+
## Command-line Usage
|
15
|
+
|
16
|
+
$ mkchain site.example.com.crt > site.example.com.chain
|
17
|
+
|
18
|
+
|
19
|
+
## Ruby Library
|
20
|
+
|
21
|
+
You can also invoke `mkchain` from Ruby code:
|
22
|
+
|
23
|
+
require 'mkchain'
|
24
|
+
chain_str = MkChain.chain(File.read(cert_filename))
|
25
|
+
|
26
|
+
This method returns a string containing the contents of the intermediate
|
27
|
+
chain in PEM format. If no chain can be built from the certificate, a
|
28
|
+
`MkChain::NoChainFoundException` will be raised. If no chain is necessary
|
29
|
+
(ie, if the certificate was signed directly by the root CA), then an empty
|
30
|
+
string will be returned.
|
31
|
+
|
32
|
+
|
33
|
+
## No guarantee
|
34
|
+
|
35
|
+
This method of building an intermediate chain depends on the signing
|
36
|
+
certificate being in the `authorityInfoAccess` X.509 extension field under
|
37
|
+
`CA Issuers`. That's a common but not universal pattern.
|
38
|
+
|
39
|
+
|
40
|
+
## Similar Tools
|
41
|
+
|
42
|
+
* https://whatsmychaincert.com/
|
43
|
+
* https://github.com/SSLMate/mkcertchain
|
data/bin/mkchain
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'mkchain'
|
4
|
+
|
5
|
+
abort 'Usage: mkchain <cert-filename>' unless ARGV.count == 1
|
6
|
+
|
7
|
+
filename = ARGV[0]
|
8
|
+
abort "No such file '#{filename}'" unless File.exist?(filename)
|
9
|
+
abort "Cannot read file '#{filename}'" unless File.readable?(filename)
|
10
|
+
|
11
|
+
puts MkChain.chain(File.read(filename))
|
data/lib/mkchain.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
class MkChain
|
5
|
+
class NoChainFoundException < Exception; end
|
6
|
+
|
7
|
+
def self.chain(cert_str)
|
8
|
+
chain = []
|
9
|
+
cert = OpenSSL::X509::Certificate.new(cert_str)
|
10
|
+
|
11
|
+
loop do
|
12
|
+
url = cert.extensions.select { |ext| ext.oid == 'authorityInfoAccess' }
|
13
|
+
.first.value.match(%r{^CA Issuers - URI:(https?://.+)$})[1] rescue break
|
14
|
+
|
15
|
+
cert = OpenSSL::X509::Certificate.new(open(url).read) rescue break
|
16
|
+
chain << cert.to_pem
|
17
|
+
end
|
18
|
+
|
19
|
+
raise NoChainFoundException, 'No intermediate chain found' if chain.empty?
|
20
|
+
|
21
|
+
# the last cert will be the root cert, which doesn't belong in the chain
|
22
|
+
chain[0..-1].join
|
23
|
+
end
|
24
|
+
end
|
data/mkchain.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'mkchain'
|
3
|
+
s.version = '1.0.2'
|
4
|
+
s.authors = ['David Adams']
|
5
|
+
s.email = 'dadams@instructure.com'
|
6
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
7
|
+
s.license = 'MIT'
|
8
|
+
s.homepage = 'https://github.com/instructure/mkchain'
|
9
|
+
s.required_ruby_version = '>=2.0.0'
|
10
|
+
|
11
|
+
s.summary = 'Create a chain file from SSL cert'
|
12
|
+
s.description =
|
13
|
+
'Creates an intermediate chain file from the given SSL certificate'
|
14
|
+
|
15
|
+
s.require_paths = ['lib']
|
16
|
+
s.files = [
|
17
|
+
'lib/mkchain.rb',
|
18
|
+
'README.md',
|
19
|
+
'mkchain.gemspec'
|
20
|
+
]
|
21
|
+
s.bindir = 'bin'
|
22
|
+
s.executables = ['mkchain']
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mkchain
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Adams
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-09-18 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Creates an intermediate chain file from the given SSL certificate
|
14
|
+
email: dadams@instructure.com
|
15
|
+
executables:
|
16
|
+
- mkchain
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- README.md
|
21
|
+
- bin/mkchain
|
22
|
+
- lib/mkchain.rb
|
23
|
+
- mkchain.gemspec
|
24
|
+
homepage: https://github.com/instructure/mkchain
|
25
|
+
licenses:
|
26
|
+
- MIT
|
27
|
+
metadata: {}
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 2.0.0
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 2.5.2
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: Create a chain file from SSL cert
|
48
|
+
test_files: []
|