cert_munger 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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