cert_munger 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8a6cf4e695d20f120b6201a5076b94ee84234f3a
4
+ data.tar.gz: 8e824b0df19568fb6d7eb2d147d238d59383215a
5
+ SHA512:
6
+ metadata.gz: 3e31741f4b5f00b870d12b45a9d504aa79f69d7dc10a08102497e8cc379ff2ba9bc777870579a79adbecfcfd52c55342fea7abaf452c2eef2423e5592fcae7bf
7
+ data.tar.gz: 2e0a2264638155ce1c67d0b8ec41f5af3cd5c4becb3c88a47da8cc2a298dc9a1733936484a93e5628ff85d14101ccf15cb285a53ad5df5934b21b3d9f4288a4a
Binary file
Binary file
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ *.bak
15
+ mkmf.log
16
+ .coveralls.yml
@@ -0,0 +1,10 @@
1
+ inherit_from: rubocop-todo.yml
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - 'cert_munger.gemspec'
6
+ - 'lib/cert_munger/version.rb'
7
+ - 'spec/**/*'
8
+ - 'vendor/cache/**/*'
9
+ - 'vendor/bundle/**/*'
10
+ - '**/gems/**/*'
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ cache: bundler
3
+
4
+ rvm:
5
+ - ruby-head
6
+ - jruby-head
7
+ - 2.1.2
8
+ - 2.1.1
9
+ - 2.0.0
10
+ - 1.9.3
11
+
12
+ script: 'bundle exec rake'
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cert_munger.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Steven Haddox
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.
@@ -0,0 +1,44 @@
1
+ [![Gem Version](https://badge.fury.io/rb/cert_munger.png)](http://badge.fury.io/rb/cert_munger) [![Coverage Status](https://coveralls.io/repos/stevenhaddox/cert_munger/badge.png)](https://coveralls.io/r/stevenhaddox/cert_munger) [![Code Climate](https://codeclimate.com/github/stevenhaddox/cert_munger/badges/gpa.svg)](https://codeclimate.com/github/stevenhaddox/cert_munger) [![Dependency Status](https://gemnasium.com/stevenhaddox/cert_munger.png)](https://gemnasium.com/stevenhaddox/cert_munger) [![Travis CI](https://travis-ci.org/stevenhaddox/cert_munger.svg?branch=master)](https://travis-ci.org/stevenhaddox/cert_munger.svg?branch=master)
2
+
3
+ # CertMunger
4
+
5
+ A gem that takes string input for X509 certificates and attempts to reformat
6
+ them into a valid certificate. This gem extends the core String class to add
7
+ the `.to_cert` and `.to_cert!` methods through the CertMunger module.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'cert_munger'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install cert_munger
24
+
25
+ ## Usage
26
+
27
+ ```ruby
28
+ # Use CertMunger on any string:
29
+ new_cert = "<invalidly formatted cert string>".to_cert
30
+
31
+ # Or a string read from a file (one or multiple lines):
32
+ bad_cert = File.read('malformed_cert_to_parse')
33
+ bad_cert.to_cert!
34
+ ```
35
+
36
+ ## Contributing
37
+
38
+ 1. Fork it ( https://github.com/stevenhaddox/cert_munger/fork )
39
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
40
+ 3. Ensure your changes have tests
41
+ 4. Run the test suite (`bundle exec rake`)
42
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
43
+ 6. Push to the branch (`git push origin my-new-feature`)
44
+ 7. Create a new Pull Request
@@ -0,0 +1,20 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+ require 'coveralls/rake/task'
5
+ Coveralls::RakeTask.new
6
+
7
+ task default: [:spec, :rubocop, 'coveralls:push']
8
+
9
+ desc 'Run specs'
10
+ RSpec::Core::RakeTask.new(:spec)
11
+
12
+ desc 'Run rubocop'
13
+ task :rubocop do
14
+ RuboCop::RakeTask.new
15
+ end
16
+
17
+ desc 'Display TODOs, FIXMEs, and OPTIMIZEs'
18
+ task :notes do
19
+ system("grep -r 'OPTIMIZE:\\|FIXME:\\|TODO:' #{Dir.pwd}")
20
+ end
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cert_munger/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cert_munger"
8
+ spec.version = CertMunger::VERSION
9
+ spec.authors = ["Steven Haddox"]
10
+ spec.email = ["steven.haddox@gmail.com"]
11
+ spec.summary = %q{Reformat commonly malformatted X509 strings.}
12
+ spec.description = %q{A gem that takes string input for X509 certificates and attempts to reformat them into a valid certificate.}
13
+ spec.homepage = "https://github.com/stevenhaddox/cert_munger"
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_dependency 'logging', '~> 1.8'
22
+
23
+ spec.add_development_dependency 'awesome_print', '~> 1.2'
24
+ spec.add_development_dependency 'bundler', '~> 1.6'
25
+ spec.add_development_dependency 'coveralls', '~> 0.7'
26
+ spec.add_development_dependency 'rack', '~> 1.5'
27
+ spec.add_development_dependency 'rack-test', '~> 0.6'
28
+ spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'rubocop', '~> 0.27'
30
+ spec.add_development_dependency 'rspec', '~> 3.1'
31
+ spec.add_development_dependency 'simplecov', '~> 0.9'
32
+ spec.add_development_dependency 'yard', '~> 0.8'
33
+
34
+ spec.cert_chain = ['certs/stevenhaddox.pem']
35
+ spec.signing_key = File.expand_path("~/.gem/certs/gem-private_key.pem") if $0 =~ /gem\z/
36
+ end
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDhTCCAm2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMRYwFAYDVQQDDA1zdGV2
3
+ ZW4uaGFkZG94MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
4
+ FgNjb20wHhcNMTQxMTE4MDIxMzIwWhcNMTUxMTE4MDIxMzIwWjBEMRYwFAYDVQQD
5
+ DA1zdGV2ZW4uaGFkZG94MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJ
6
+ k/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDanmKr
7
+ vJDcVGMeDbDouLfKvU5ugOcHTXP04QDYSshaMTeuWSm4OXakxk2rxnR7Laq86R+8
8
+ h1NbHMdiZdwlHcpZm9/YD6qjbQhnLNGsezMrNpfZwfy9VnUQY4e0OCAca9vQXKTL
9
+ qC4fiuRD6sQQpyXkiIno0KlJOA4sKtH8vFucPGmhO0FUdlQY5FarDvCvZrtteO6L
10
+ 6/GQFjupFBd9X6zt1XBs28IC+YUw33SN0UJ5JHB45ig0BmeWMXdd4SKWe4ve/2UY
11
+ asgs2miI3HP0wCPs0EF64/8LbuEUyMjHDr3a7+7KIRxYn2H/yUH5Ndqz6yL5G0sf
12
+ jUsC32JuE7VlJwFNAgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAd
13
+ BgNVHQ4EFgQUC8HywyOMPJFCsH7uGW+CeKcZ8+8wIgYDVR0RBBswGYEXc3RldmVu
14
+ LmhhZGRveEBnbWFpbC5jb20wIgYDVR0SBBswGYEXc3RldmVuLmhhZGRveEBnbWFp
15
+ bC5jb20wDQYJKoZIhvcNAQEFBQADggEBAFoac9ZKc20ZXw2R2mWUz7FaJJdUvb7o
16
+ 4rKVzFQkJwvAX+NEdP32yCDViGoEqlA13el5fllllmG3E7Qrw+0JA5B3wrZbVfQA
17
+ v4eX0ZohhW3CXLSz65pd3zfrwPAw0pXs1QKP+IioTuLQoBsGUiIqCPulZvzn/xN2
18
+ KG7SexyfUEXyJRMMigA/mE8h6bYfgKKUmLQVs1uRaXmOI7dKUF6HZJpda51zJH3v
19
+ 42qdwEXvvkODZAD6KAIXPdmbMfBgPbcd+B/4eUA0PyKo+4dgL1NuqX4MPWToevIZ
20
+ O8EKLF2X7NmC6FY1bOsSj/J8r1SOkx0rxgF+geRvY1P+hfNjDfxTsjU=
21
+ -----END CERTIFICATE-----
@@ -0,0 +1,3 @@
1
+ require 'cert_munger/version'
2
+ require 'cert_munger/formatter'
3
+ require 'cert_munger/string'
@@ -0,0 +1,62 @@
1
+ require 'logging'
2
+ class UnparsableCertError < TypeError; end
3
+
4
+ #
5
+ # CertMunger accepts an input string and attempts to return a valid X509
6
+ # formatted certificate.
7
+ #
8
+ module CertMunger
9
+ def self.included(base)
10
+ base.extend(ClassMethods)
11
+ end
12
+
13
+ def to_cert(raw_cert)
14
+ self.class.send(:to_cert, raw_cert)
15
+ end
16
+
17
+ #
18
+ # Extended class methods via `include CertMunger`
19
+ #
20
+ module ClassMethods
21
+ def logger
22
+ return @logger if @logger
23
+ logger = Logging.logger[self] unless @logger
24
+ @logger ||= Kernel.const_defined?('Rails') ? Rails.logger : logger
25
+ end
26
+
27
+ def to_cert(raw_cert)
28
+ logger.debug "CertMunger raw_cert:\n#{raw_cert}"
29
+ new_cert = build_cert(raw_cert)
30
+ logger.debug "CertMunger reformatted_cert:\n#{new_cert}"
31
+ logger.debug 'Returning OpenSSL::X509::Certificate.new on new_cert'
32
+
33
+ OpenSSL::X509::Certificate.new new_cert
34
+ end
35
+
36
+ def build_cert(raw_cert)
37
+ tmp_cert = ['-----BEGIN CERTIFICATE-----']
38
+ if raw_cert.lines.count == 1
39
+ cert_contents = one_line_contents(raw_cert)
40
+ else
41
+ cert_contents = multi_line_contents(raw_cert)
42
+ end
43
+ tmp_cert << cert_contents.flatten # put mixed space lines as own elements
44
+ tmp_cert << '-----END CERTIFICATE-----'
45
+ tmp_cert.join("\n").rstrip
46
+ end
47
+
48
+ def one_line_contents(raw_cert)
49
+ cert_contents = raw_cert.split('\n')
50
+ cert_contents.pop
51
+ cert_contents.shift
52
+ cert_contents.map! { |el| el.match('\W+[t|n|r](.*)')[1] }
53
+ end
54
+
55
+ def multi_line_contents(raw_cert)
56
+ cert_contents = raw_cert.split(/[-](.*)[-]/)[2]
57
+ cert_contents.lines.map do |line|
58
+ line.lstrip.squeeze(' ').split(' ')
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,28 @@
1
+ class String # rubocop:disable Documentation
2
+ include CertMunger
3
+
4
+ # Returns an X509 certificate after parsing the value of this object.
5
+ # Returns false if an X509 certificate cannot be created.
6
+ def to_cert
7
+ begin
8
+ new_cert = self.class.send(:to_cert, self)
9
+ rescue StandardError
10
+ new_cert = false
11
+ end
12
+
13
+ new_cert
14
+ end
15
+
16
+ # Similar to {#to_cert}, but raises an error unless the string can be
17
+ # explicitly parsed to an X509 certifcate.
18
+ def to_cert!
19
+ begin
20
+ new_cert = self.class.send(:to_cert, self)
21
+ rescue StandardError
22
+ raise UnparsableCertError,
23
+ "Could not force conversion to X509:\n#{inspect}"
24
+ end
25
+
26
+ new_cert
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module CertMunger
2
+ VERSION = "0.0.1"
3
+ end
File without changes
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'openssl'
4
+ require 'awesome_print'
5
+
6
+ root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
7
+ root_ca = OpenSSL::X509::Certificate.new
8
+ root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
9
+ root_ca.serial = 1
10
+ root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA"
11
+ root_ca.issuer = root_ca.subject # root CA's are "self-signed"
12
+ root_ca.public_key = root_key.public_key
13
+ root_ca.not_before = Time.now
14
+ root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
15
+ ef = OpenSSL::X509::ExtensionFactory.new
16
+ ef.subject_certificate = root_ca
17
+ ef.issuer_certificate = root_ca
18
+ root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
19
+ root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
20
+ root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
21
+ root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
22
+ root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
23
+
24
+ key = OpenSSL::PKey::RSA.new 2048
25
+ cert = OpenSSL::X509::Certificate.new
26
+ cert.version = 2
27
+ cert.serial = 2
28
+ cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate rbcert"
29
+ cert.issuer = root_ca.subject # root CA is the issuer
30
+ cert.public_key = key.public_key
31
+ cert.not_before = Time.now
32
+ cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity
33
+ ef = OpenSSL::X509::ExtensionFactory.new
34
+ ef.subject_certificate = cert
35
+ ef.issuer_certificate = root_ca
36
+ cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
37
+ cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
38
+ cert.sign(root_key, OpenSSL::Digest::SHA256.new)
39
+
40
+ File.write('ruby_user.crt', cert)
41
+ File.write('ruby_user.pub', cert.public_key)
@@ -0,0 +1,18 @@
1
+ -----BEGIN CERTIFICATE----- MIIDQDCCAiigAwIBAgIBAjANBgkqhkiG9w0BAQsFADBCMRMwEQYKCZImiZPyLGQB
2
+ GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQDDAdSdWJ5
3
+ IENBMB4XDTE0MTAyMTE0MTU0NFoXDTE1MTAyMTE0MTU0NFowUjETMBEGCgmSJomT
4
+ 8ixkARkWA29yZzEZMBcGCgmSJomT8ixkARkWCXJ1YnktbGFuZzEgMB4GA1UEAwwX
5
+ UnVieSBjZXJ0aWZpY2F0ZSByYmNlcnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
6
+ ggEKAoIBAQDA2Cb1QoNx7ghJv/q7yzAr89zyQbOr7wJN+X9/qfRTZi7o31JRrO21
7
+ 4VFAQeLdf2InfH/yGcME/6dRm0Y9priOShPkRTrerxD8Xf7df/u/R2cUW6WcQUuB
8
+ fFHp8f1FcYuwxsX2gFNpboukRfWSgIvkXG+BAl/HSUjPyjiEYYTk2nkjOUmFObA8
9
+ ip7xJ2n+ZyHl4SggvC+C8QmDQt3dBsZ3C2BovtJ6YQRMJjaEXGWl2fxJfgnJ94aq /M3TP5OUvnwDh8MJq4LuPNPc2PBAAvrQ0SFUaZxlxt9cWtnEGhT6jejBWrik8BNk
10
+ YGrU9HIpYeg4a9i5GRDZ6s/xlZ4X+pjlAgMBAAGjMTAvMA4GA1UdDwEB/wQEAwIH
11
+ gDAdBgNVHQ4EFgQUPGVKgxbUCl/OiPHnzeN3qR5BMe4wDQYJKoZIhvcNAQELBQAD
12
+ ggEBAFnSbIvnYubRuEcGux5m1y2UlzSg/GyNDhnWsfPqQQ7FfolFTk6W8+xKuRSg
13
+ foiuV2Od0n1nBMd9ePzoF5QabMHCK1Al2o/P7PkUPgmuAnWWdTLikNtt6H6v9WLe
14
+ R9Ng37xv9jOVFOQjYCYvc94cJe1OBXW7ppkRY3kUQQbIrO7Imwi8gB8KT4qwu/Ld
15
+ Xt53I/aFMQ0JSkqhJ4Bhff/Ol2RcDjEt4U6Hne6lRVB9qCAz0gE8MN4HagWOlS1U
16
+ Nxd+cde+JIVBHuDz63gExGPCdLBRL/Mi3LORpZT41/ryw3JCqTir0dgPXsVTtJPr
17
+ iMZ2EcsmShyBUKKj2AIok5gZzgM=
18
+ -----END CERTIFICATE-----
@@ -0,0 +1 @@
1
+ -----BEGIN CERTIFICATE-----\n\tMIIDQDCCAiigAwIBAgIBAjANBgkqhkiG9w0BAQsFADBCMRMwEQYKCZImiZPyLGQB\n\tGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQDDAdSdWJ5\n\tIENBMB4XDTE0MTAyMTE0MTU0NFoXDTE1MTAyMTE0MTU0NFowUjETMBEGCgmSJomT\n\t8ixkARkWA29yZzEZMBcGCgmSJomT8ixkARkWCXJ1YnktbGFuZzEgMB4GA1UEAwwX\n\tUnVieSBjZXJ0aWZpY2F0ZSByYmNlcnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\n\tggEKAoIBAQDA2Cb1QoNx7ghJv/q7yzAr89zyQbOr7wJN+X9/qfRTZi7o31JRrO21\n\t4VFAQeLdf2InfH/yGcME/6dRm0Y9priOShPkRTrerxD8Xf7df/u/R2cUW6WcQUuB\n\tfFHp8f1FcYuwxsX2gFNpboukRfWSgIvkXG+BAl/HSUjPyjiEYYTk2nkjOUmFObA8\n\tip7xJ2n+ZyHl4SggvC+C8QmDQt3dBsZ3C2BovtJ6YQRMJjaEXGWl2fxJfgnJ94aq\n\t/M3TP5OUvnwDh8MJq4LuPNPc2PBAAvrQ0SFUaZxlxt9cWtnEGhT6jejBWrik8BNk\n\tYGrU9HIpYeg4a9i5GRDZ6s/xlZ4X+pjlAgMBAAGjMTAvMA4GA1UdDwEB/wQEAwIH\n\tgDAdBgNVHQ4EFgQUPGVKgxbUCl/OiPHnzeN3qR5BMe4wDQYJKoZIhvcNAQELBQAD\n\tggEBAFnSbIvnYubRuEcGux5m1y2UlzSg/GyNDhnWsfPqQQ7FfolFTk6W8+xKuRSg\n\tfoiuV2Od0n1nBMd9ePzoF5QabMHCK1Al2o/P7PkUPgmuAnWWdTLikNtt6H6v9WLe\n\tR9Ng37xv9jOVFOQjYCYvc94cJe1OBXW7ppkRY3kUQQbIrO7Imwi8gB8KT4qwu/Ld\n\tXt53I/aFMQ0JSkqhJ4Bhff/Ol2RcDjEt4U6Hne6lRVB9qCAz0gE8MN4HagWOlS1U\n\tNxd+cde+JIVBHuDz63gExGPCdLBRL/Mi3LORpZT41/ryw3JCqTir0dgPXsVTtJPr\n\tiMZ2EcsmShyBUKKj2AIok5gZzgM=\n\t-----END CERTIFICATE-----
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDQDCCAiigAwIBAgIBAjANBgkqhkiG9w0BAQsFADBCMRMwEQYKCZImiZPyLGQB
3
+ GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQDDAdSdWJ5
4
+ IENBMB4XDTE0MTAyMTE0MTU0NFoXDTE1MTAyMTE0MTU0NFowUjETMBEGCgmSJomT
5
+ 8ixkARkWA29yZzEZMBcGCgmSJomT8ixkARkWCXJ1YnktbGFuZzEgMB4GA1UEAwwX
6
+ UnVieSBjZXJ0aWZpY2F0ZSByYmNlcnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
7
+ ggEKAoIBAQDA2Cb1QoNx7ghJv/q7yzAr89zyQbOr7wJN+X9/qfRTZi7o31JRrO21
8
+ 4VFAQeLdf2InfH/yGcME/6dRm0Y9priOShPkRTrerxD8Xf7df/u/R2cUW6WcQUuB
9
+ fFHp8f1FcYuwxsX2gFNpboukRfWSgIvkXG+BAl/HSUjPyjiEYYTk2nkjOUmFObA8
10
+ ip7xJ2n+ZyHl4SggvC+C8QmDQt3dBsZ3C2BovtJ6YQRMJjaEXGWl2fxJfgnJ94aq
11
+ /M3TP5OUvnwDh8MJq4LuPNPc2PBAAvrQ0SFUaZxlxt9cWtnEGhT6jejBWrik8BNk
12
+ YGrU9HIpYeg4a9i5GRDZ6s/xlZ4X+pjlAgMBAAGjMTAvMA4GA1UdDwEB/wQEAwIH
13
+ gDAdBgNVHQ4EFgQUPGVKgxbUCl/OiPHnzeN3qR5BMe4wDQYJKoZIhvcNAQELBQAD
14
+ ggEBAFnSbIvnYubRuEcGux5m1y2UlzSg/GyNDhnWsfPqQQ7FfolFTk6W8+xKuRSg
15
+ foiuV2Od0n1nBMd9ePzoF5QabMHCK1Al2o/P7PkUPgmuAnWWdTLikNtt6H6v9WLe
16
+ R9Ng37xv9jOVFOQjYCYvc94cJe1OBXW7ppkRY3kUQQbIrO7Imwi8gB8KT4qwu/Ld
17
+ Xt53I/aFMQ0JSkqhJ4Bhff/Ol2RcDjEt4U6Hne6lRVB9qCAz0gE8MN4HagWOlS1U
18
+ Nxd+cde+JIVBHuDz63gExGPCdLBRL/Mi3LORpZT41/ryw3JCqTir0dgPXsVTtJPr
19
+ iMZ2EcsmShyBUKKj2AIok5gZzgM=
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDQDCCAiigAwIBAgIBAjANBgkqhkiG9w0BAQsFADBCMRMwEQYKCZImiZPyLGQB
3
+ GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQDDAdSdWJ5
4
+ IENBMB4XDTE0MTAyMTE0MTU0NFoXDTE1MTAyMTE0MTU0NFowUjETMBEGCgmSJomT
5
+ 8ixkARkWA29yZzEZMBcGCgmSJomT8ixkARkWCXJ1YnktbGFuZzEgMB4GA1UEAwwX
6
+ UnVieSBjZXJ0aWZpY2F0ZSByYmNlcnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
7
+ ggEKAoIBAQDA2Cb1QoNx7ghJv/q7yzAr89zyQbOr7wJN+X9/qfRTZi7o31JRrO21
8
+ 4VFAQeLdf2InfH/yGcME/6dRm0Y9priOShPkRTrerxD8Xf7df/u/R2cUW6WcQUuB
9
+ fFHp8f1FcYuwxsX2gFNpboukRfWSgIvkXG+BAl/HSUjPyjiEYYTk2nkjOUmFObA8
10
+ ip7xJ2n+ZyHl4SggvC+C8QmDQt3dBsZ3C2BovtJ6YQRMJjaEXGWl2fxJfgnJ94aq
11
+ /M3TP5OUvnwDh8MJq4LuPNPc2PBAAvrQ0SFUaZxlxt9cWtnEGhT6jejBWrik8BNk
12
+ YGrU9HIpYeg4a9i5GRDZ6s/xlZ4X+pjlAgMBAAGjMTAvMA4GA1UdDwEB/wQEAwIH
13
+ gDAdBgNVHQ4EFgQUPGVKgxbUCl/OiPHnzeN3qR5BMe4wDQYJKoZIhvcNAQELBQAD
14
+ ggEBAFnSbIvnYubRuEcGux5m1y2UlzSg/GyNDhnWsfPqQQ7FfolFTk6W8+xKuRSg
15
+ foiuV2Od0n1nBMd9ePzoF5QabMHCK1Al2o/P7PkUPgmuAnWWdTLikNtt6H6v9WLe
16
+ R9Ng37xv9jOVFOQjYCYvc94cJe1OBXW7ppkRY3kUQQbIrO7Imwi8gB8KT4qwu/Ld
17
+ Xt53I/aFMQ0JSkqhJ4Bhff/Ol2RcDjEt4U6Hne6lRVB9qCAz0gE8MN4HagWOlS1U
18
+ Nxd+cde+JIVBHuDz63gExGPCdLBRL/Mi3LORpZT41/ryw3JCqTir0dgPXsVTtJPr
19
+ iMZ2EcsmShyBUKKj2AIok5gZzgM=
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,9 @@
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwNgm9UKDce4ISb/6u8sw
3
+ K/Pc8kGzq+8CTfl/f6n0U2Yu6N9SUaztteFRQEHi3X9iJ3x/8hnDBP+nUZtGPaa4
4
+ jkoT5EU63q8Q/F3+3X/7v0dnFFulnEFLgXxR6fH9RXGLsMbF9oBTaW6LpEX1koCL
5
+ 5FxvgQJfx0lIz8o4hGGE5Np5IzlJhTmwPIqe8Sdp/mch5eEoILwvgvEJg0Ld3QbG
6
+ dwtgaL7SemEETCY2hFxlpdn8SX4JyfeGqvzN0z+TlL58A4fDCauC7jzT3NjwQAL6
7
+ 0NEhVGmcZcbfXFrZxBoU+o3owVq4pPATZGBq1PRyKWHoOGvYuRkQ2erP8ZWeF/qY
8
+ 5QIDAQAB
9
+ -----END PUBLIC KEY-----
@@ -0,0 +1,57 @@
1
+ require "spec_helper"
2
+ require "openssl"
3
+
4
+ describe CertMunger do
5
+ let(:class_including_cert_munger) {
6
+ Class.new do
7
+ include CertMunger
8
+ Logging.logger[self].level = :warn
9
+ end
10
+ }
11
+
12
+ subject { class_including_cert_munger.new }
13
+ let!(:raw_cert) { File.read("spec/certs/ruby_user.crt") }
14
+ let(:pub_key) { File.read("spec/certs/ruby_user.pub") }
15
+ let!(:certificate) { OpenSSL::X509::Certificate.new(raw_cert) }
16
+ let!(:malformed_cert) { File.read("spec/certs/malformed.crt") }
17
+ let!(:one_line_cert) { File.read("spec/certs/one_line.crt") }
18
+ let!(:passenger_nginx_cert) { File.read("spec/certs/passenger.crt") }
19
+
20
+ #
21
+ # Unit specs
22
+ #
23
+
24
+ describe ".to_cert" do
25
+ it "should parse a certificate with invalid spacing/newlines" do
26
+ new_cert = subject.to_cert(malformed_cert)
27
+ expect(new_cert.to_s).to eq(certificate.to_s)
28
+ end
29
+
30
+ it "should parse a certificate with passenger formatted spacing/newlines" do
31
+ new_cert = subject.to_cert(passenger_nginx_cert)
32
+ expect(new_cert.to_s).to eq(certificate.to_s)
33
+ end
34
+
35
+ it "should parse a certificate with all content in one line" do
36
+ new_cert = subject.to_cert(one_line_cert)
37
+ expect(new_cert.to_s).to eq(certificate.to_s)
38
+ end
39
+ end
40
+
41
+ describe "#to_cert" do
42
+ it "should parse a certificate with invalid spacing/newlines" do
43
+ new_cert = subject.class.send(:to_cert, malformed_cert)
44
+ expect(new_cert.to_s).to eq(certificate.to_s)
45
+ end
46
+
47
+ it "should parse a certificate with passenger formatted spacing/newlines" do
48
+ new_cert = subject.class.send(:to_cert, passenger_nginx_cert)
49
+ expect(new_cert.to_s).to eq(certificate.to_s)
50
+ end
51
+
52
+ it "should parse a certificate with all content in one line" do
53
+ new_cert = subject.class.send(:to_cert, one_line_cert)
54
+ expect(new_cert.to_s).to eq(certificate.to_s)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe String do
4
+ let!(:raw_cert) { File.read("spec/certs/ruby_user.crt") }
5
+ let!(:certificate) { OpenSSL::X509::Certificate.new(raw_cert) }
6
+ let!(:malformed_cert) { File.read("spec/certs/malformed.crt") }
7
+ let!(:one_line_cert) { File.read("spec/certs/one_line.crt") }
8
+ let!(:passenger_nginx_cert) { File.read("spec/certs/passenger.crt") }
9
+
10
+ after :all do
11
+ expect(@log_output.readline).to eq("DEBUG String : CertMunger raw_cert:\n")
12
+ end
13
+
14
+ describe ".to_cert" do
15
+ it "should return an X509 certificate if the string can be parsed" do
16
+ expect(passenger_nginx_cert.to_cert.to_s).to eq(certificate.to_s)
17
+ expect(malformed_cert.to_cert.to_s).to eq(certificate.to_s)
18
+ expect(one_line_cert.to_cert.to_s).to eq(certificate.to_s)
19
+ end
20
+
21
+ it "should return false otherwise" do
22
+ expect("".to_cert).to eql(false)
23
+ expect("nope".to_cert).to eql(false)
24
+ end
25
+ end
26
+
27
+ describe ".to_cert!" do
28
+ it "should return an X509 certificate if the string can be parsed" do
29
+ expect(passenger_nginx_cert.to_cert!.to_s).to eq(certificate.to_s)
30
+ expect(malformed_cert.to_cert!.to_s).to eq(certificate.to_s)
31
+ expect(one_line_cert.to_cert!.to_s).to eq(certificate.to_s)
32
+ end
33
+
34
+ it "should raise an UnparsableCert error otherwise" do
35
+ expect{ "".to_cert! }.to raise_error(UnparsableCertError)
36
+ expect{ "nope".to_cert! }.to raise_error(UnparsableCertError)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
4
+ SimpleCov.start do
5
+ add_filter '/spec/'
6
+ end
7
+ # SimpleCov always comes before **anything** else
8
+
9
+ require_relative '../lib/cert_munger'
10
+ require 'awesome_print'
11
+ require 'rspec/logging_helper'
12
+
13
+ RSpec.configure do |config|
14
+ config.run_all_when_everything_filtered = true
15
+ config.filter_run :focus
16
+ config.filter_run_excluding :skip
17
+ config.order = 'random'
18
+
19
+ # Configure RSpec to capture log messages for each test. The output from the
20
+ # logs will be stored in the @log_output variable. It is a StringIO instance.
21
+ include RSpec::LoggingHelper
22
+ config.capture_log_messages
23
+ end
metadata ADDED
@@ -0,0 +1,254 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cert_munger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Steven Haddox
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDhTCCAm2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMRYwFAYDVQQDDA1zdGV2
14
+ ZW4uaGFkZG94MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
15
+ FgNjb20wHhcNMTQxMTE4MDIxMzIwWhcNMTUxMTE4MDIxMzIwWjBEMRYwFAYDVQQD
16
+ DA1zdGV2ZW4uaGFkZG94MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJ
17
+ k/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDanmKr
18
+ vJDcVGMeDbDouLfKvU5ugOcHTXP04QDYSshaMTeuWSm4OXakxk2rxnR7Laq86R+8
19
+ h1NbHMdiZdwlHcpZm9/YD6qjbQhnLNGsezMrNpfZwfy9VnUQY4e0OCAca9vQXKTL
20
+ qC4fiuRD6sQQpyXkiIno0KlJOA4sKtH8vFucPGmhO0FUdlQY5FarDvCvZrtteO6L
21
+ 6/GQFjupFBd9X6zt1XBs28IC+YUw33SN0UJ5JHB45ig0BmeWMXdd4SKWe4ve/2UY
22
+ asgs2miI3HP0wCPs0EF64/8LbuEUyMjHDr3a7+7KIRxYn2H/yUH5Ndqz6yL5G0sf
23
+ jUsC32JuE7VlJwFNAgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAd
24
+ BgNVHQ4EFgQUC8HywyOMPJFCsH7uGW+CeKcZ8+8wIgYDVR0RBBswGYEXc3RldmVu
25
+ LmhhZGRveEBnbWFpbC5jb20wIgYDVR0SBBswGYEXc3RldmVuLmhhZGRveEBnbWFp
26
+ bC5jb20wDQYJKoZIhvcNAQEFBQADggEBAFoac9ZKc20ZXw2R2mWUz7FaJJdUvb7o
27
+ 4rKVzFQkJwvAX+NEdP32yCDViGoEqlA13el5fllllmG3E7Qrw+0JA5B3wrZbVfQA
28
+ v4eX0ZohhW3CXLSz65pd3zfrwPAw0pXs1QKP+IioTuLQoBsGUiIqCPulZvzn/xN2
29
+ KG7SexyfUEXyJRMMigA/mE8h6bYfgKKUmLQVs1uRaXmOI7dKUF6HZJpda51zJH3v
30
+ 42qdwEXvvkODZAD6KAIXPdmbMfBgPbcd+B/4eUA0PyKo+4dgL1NuqX4MPWToevIZ
31
+ O8EKLF2X7NmC6FY1bOsSj/J8r1SOkx0rxgF+geRvY1P+hfNjDfxTsjU=
32
+ -----END CERTIFICATE-----
33
+ date: 2014-11-18 00:00:00.000000000 Z
34
+ dependencies:
35
+ - !ruby/object:Gem::Dependency
36
+ name: logging
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.8'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.8'
49
+ - !ruby/object:Gem::Dependency
50
+ name: awesome_print
51
+ requirement: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.2'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '1.2'
63
+ - !ruby/object:Gem::Dependency
64
+ name: bundler
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.6'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.6'
77
+ - !ruby/object:Gem::Dependency
78
+ name: coveralls
79
+ requirement: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0.7'
84
+ type: :development
85
+ prerelease: false
86
+ version_requirements: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '0.7'
91
+ - !ruby/object:Gem::Dependency
92
+ name: rack
93
+ requirement: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '1.5'
98
+ type: :development
99
+ prerelease: false
100
+ version_requirements: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '1.5'
105
+ - !ruby/object:Gem::Dependency
106
+ name: rack-test
107
+ requirement: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '0.6'
112
+ type: :development
113
+ prerelease: false
114
+ version_requirements: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '0.6'
119
+ - !ruby/object:Gem::Dependency
120
+ name: rake
121
+ requirement: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '10.0'
126
+ type: :development
127
+ prerelease: false
128
+ version_requirements: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: '10.0'
133
+ - !ruby/object:Gem::Dependency
134
+ name: rubocop
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '0.27'
140
+ type: :development
141
+ prerelease: false
142
+ version_requirements: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - "~>"
145
+ - !ruby/object:Gem::Version
146
+ version: '0.27'
147
+ - !ruby/object:Gem::Dependency
148
+ name: rspec
149
+ requirement: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - "~>"
152
+ - !ruby/object:Gem::Version
153
+ version: '3.1'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - "~>"
159
+ - !ruby/object:Gem::Version
160
+ version: '3.1'
161
+ - !ruby/object:Gem::Dependency
162
+ name: simplecov
163
+ requirement: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - "~>"
166
+ - !ruby/object:Gem::Version
167
+ version: '0.9'
168
+ type: :development
169
+ prerelease: false
170
+ version_requirements: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - "~>"
173
+ - !ruby/object:Gem::Version
174
+ version: '0.9'
175
+ - !ruby/object:Gem::Dependency
176
+ name: yard
177
+ requirement: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - "~>"
180
+ - !ruby/object:Gem::Version
181
+ version: '0.8'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - "~>"
187
+ - !ruby/object:Gem::Version
188
+ version: '0.8'
189
+ description: A gem that takes string input for X509 certificates and attempts to reformat
190
+ them into a valid certificate.
191
+ email:
192
+ - steven.haddox@gmail.com
193
+ executables: []
194
+ extensions: []
195
+ extra_rdoc_files: []
196
+ files:
197
+ - ".gitignore"
198
+ - ".rubocop.yml"
199
+ - ".travis.yml"
200
+ - Gemfile
201
+ - LICENSE.txt
202
+ - README.md
203
+ - Rakefile
204
+ - cert_munger.gemspec
205
+ - certs/stevenhaddox.pem
206
+ - lib/cert_munger.rb
207
+ - lib/cert_munger/formatter.rb
208
+ - lib/cert_munger/string.rb
209
+ - lib/cert_munger/version.rb
210
+ - rubocop-todo.yml
211
+ - spec/certs/create_spec_cert.rb
212
+ - spec/certs/malformed.crt
213
+ - spec/certs/one_line.crt
214
+ - spec/certs/passenger.crt
215
+ - spec/certs/ruby_user.crt
216
+ - spec/certs/ruby_user.pub
217
+ - spec/lib/cert_munger_spec.rb
218
+ - spec/lib/string_spec.rb
219
+ - spec/spec_helper.rb
220
+ homepage: https://github.com/stevenhaddox/cert_munger
221
+ licenses:
222
+ - MIT
223
+ metadata: {}
224
+ post_install_message:
225
+ rdoc_options: []
226
+ require_paths:
227
+ - lib
228
+ required_ruby_version: !ruby/object:Gem::Requirement
229
+ requirements:
230
+ - - ">="
231
+ - !ruby/object:Gem::Version
232
+ version: '0'
233
+ required_rubygems_version: !ruby/object:Gem::Requirement
234
+ requirements:
235
+ - - ">="
236
+ - !ruby/object:Gem::Version
237
+ version: '0'
238
+ requirements: []
239
+ rubyforge_project:
240
+ rubygems_version: 2.2.2
241
+ signing_key:
242
+ specification_version: 4
243
+ summary: Reformat commonly malformatted X509 strings.
244
+ test_files:
245
+ - spec/certs/create_spec_cert.rb
246
+ - spec/certs/malformed.crt
247
+ - spec/certs/one_line.crt
248
+ - spec/certs/passenger.crt
249
+ - spec/certs/ruby_user.crt
250
+ - spec/certs/ruby_user.pub
251
+ - spec/lib/cert_munger_spec.rb
252
+ - spec/lib/string_spec.rb
253
+ - spec/spec_helper.rb
254
+ has_rdoc:
Binary file