certificate_authority 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +2 -8
  6. data/Gemfile.lock +71 -27
  7. data/README.rdoc +184 -89
  8. data/Rakefile +6 -41
  9. data/certificate_authority.gemspec +22 -81
  10. data/lib/certificate_authority.rb +7 -6
  11. data/lib/certificate_authority/certificate.rb +151 -71
  12. data/lib/certificate_authority/certificate_revocation_list.rb +46 -26
  13. data/lib/certificate_authority/core_extensions.rb +46 -0
  14. data/lib/certificate_authority/distinguished_name.rb +84 -17
  15. data/lib/certificate_authority/extensions.rb +483 -96
  16. data/lib/certificate_authority/key_material.rb +75 -21
  17. data/lib/certificate_authority/ocsp_handler.rb +99 -29
  18. data/lib/certificate_authority/pkcs11_key_material.rb +13 -15
  19. data/lib/certificate_authority/revocable.rb +14 -0
  20. data/lib/certificate_authority/serial_number.rb +18 -5
  21. data/lib/certificate_authority/signing_entity.rb +5 -7
  22. data/lib/certificate_authority/signing_request.rb +91 -0
  23. data/lib/certificate_authority/validations.rb +31 -0
  24. data/lib/certificate_authority/version.rb +3 -0
  25. metadata +96 -94
  26. data/VERSION.yml +0 -5
  27. data/spec/spec_helper.rb +0 -4
  28. data/spec/units/certificate_authority_spec.rb +0 -4
  29. data/spec/units/certificate_revocation_list_spec.rb +0 -68
  30. data/spec/units/certificate_spec.rb +0 -351
  31. data/spec/units/distinguished_name_spec.rb +0 -38
  32. data/spec/units/extensions_spec.rb +0 -53
  33. data/spec/units/key_material_spec.rb +0 -96
  34. data/spec/units/ocsp_handler_spec.rb +0 -104
  35. data/spec/units/serial_number_spec.rb +0 -20
  36. data/spec/units/signing_entity_spec.rb +0 -4
  37. data/spec/units/units_helper.rb +0 -1
@@ -0,0 +1,91 @@
1
+ module CertificateAuthority
2
+ class SigningRequest
3
+ attr_accessor :distinguished_name
4
+ attr_accessor :key_material
5
+ attr_accessor :raw_body
6
+ attr_accessor :openssl_csr
7
+ attr_accessor :digest
8
+ attr_accessor :attributes
9
+
10
+ def initialize()
11
+ @attributes = []
12
+ end
13
+
14
+ # Fake attribute for convenience because adding
15
+ # alternative names on a CSR is remarkably non-trivial.
16
+ def subject_alternative_names=(alt_names)
17
+ raise "alt_names must be an Array" unless alt_names.is_a?(Array)
18
+
19
+ factory = OpenSSL::X509::ExtensionFactory.new
20
+ name_list = alt_names.map{|m| "DNS:#{m}"}.join(",")
21
+ ext = factory.create_ext("subjectAltName",name_list,false)
22
+ ext_set = OpenSSL::ASN1::Set([OpenSSL::ASN1::Sequence([ext])])
23
+ attr = OpenSSL::X509::Attribute.new("extReq", ext_set)
24
+ @attributes << attr
25
+ end
26
+
27
+ def read_attributes_by_oid(*oids)
28
+ attributes.detect { |a| oids.include?(a.oid) }
29
+ end
30
+ protected :read_attributes_by_oid
31
+
32
+ def to_cert
33
+ cert = Certificate.new
34
+ if !@distinguished_name.nil?
35
+ cert.distinguished_name = @distinguished_name
36
+ end
37
+ cert.key_material = @key_material
38
+ if attribute = read_attributes_by_oid('extReq', 'msExtReq')
39
+ set = OpenSSL::ASN1.decode(attribute.value)
40
+ seq = set.value.first
41
+ seq.value.collect { |asn1ext| OpenSSL::X509::Extension.new(asn1ext).to_a }.each do |o, v, c|
42
+ Certificate::EXTENSIONS.each do |klass|
43
+ cert.extensions[klass::OPENSSL_IDENTIFIER] = klass.parse(v, c) if v && klass::OPENSSL_IDENTIFIER == o
44
+ end
45
+ end
46
+ end
47
+ cert
48
+ end
49
+
50
+ def to_pem
51
+ to_x509_csr.to_pem
52
+ end
53
+
54
+ def to_x509_csr
55
+ raise "Must specify a DN/subject on csr" if @distinguished_name.nil?
56
+ raise "Invalid DN in request" unless @distinguished_name.valid?
57
+ raise "CSR must have key material" if @key_material.nil?
58
+ raise "CSR must include a public key on key material" if @key_material.public_key.nil?
59
+ raise "Need a private key on key material for CSR generation" if @key_material.private_key.nil?
60
+
61
+ opensslcsr = OpenSSL::X509::Request.new
62
+ opensslcsr.subject = @distinguished_name.to_x509_name
63
+ opensslcsr.public_key = @key_material.public_key
64
+ opensslcsr.attributes = @attributes unless @attributes.nil?
65
+ opensslcsr.sign @key_material.private_key, OpenSSL::Digest.new(@digest || "SHA512")
66
+ opensslcsr
67
+ end
68
+
69
+ def self.from_x509_csr(raw_csr)
70
+ csr = SigningRequest.new
71
+ openssl_csr = OpenSSL::X509::Request.new(raw_csr)
72
+ csr.distinguished_name = DistinguishedName.from_openssl openssl_csr.subject
73
+ csr.raw_body = raw_csr
74
+ csr.openssl_csr = openssl_csr
75
+ csr.attributes = openssl_csr.attributes
76
+ key_material = SigningRequestKeyMaterial.new
77
+ key_material.public_key = openssl_csr.public_key
78
+ csr.key_material = key_material
79
+ csr
80
+ end
81
+
82
+ def self.from_netscape_spkac(raw_spkac)
83
+ openssl_spkac = OpenSSL::Netscape::SPKI.new raw_spkac
84
+ csr = SigningRequest.new
85
+ csr.raw_body = raw_spkac
86
+ key_material = SigningRequestKeyMaterial.new
87
+ key_material.public_key = openssl_spkac.public_key
88
+ csr
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,31 @@
1
+ #
2
+ # This is a super simple replacement for ActiveSupport::Validations
3
+ #
4
+
5
+ module CertificateAuthority
6
+ class Errors < Array
7
+ def add(symbol, msg)
8
+ self.push([symbol, msg])
9
+ end
10
+ def full_messages
11
+ self.map {|i| i[0].to_s + ": " + i[1]}.join("\n")
12
+ end
13
+ end
14
+
15
+ module Validations
16
+ def valid?
17
+ @errors = Errors.new
18
+ validate
19
+ errors.empty?
20
+ end
21
+
22
+ # must be overridden
23
+ def validate
24
+ raise NotImplementedError
25
+ end
26
+
27
+ def errors
28
+ @errors ||= Errors.new
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module CertificateAuthority
2
+ VERSION = '1.0.0'.freeze
3
+ end
metadata CHANGED
@@ -1,137 +1,139 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: certificate_authority
3
- version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.1.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
6
5
  platform: ruby
7
- authors:
6
+ authors:
8
7
  - Chris Chandler
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
-
13
- date: 2011-04-21 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: activemodel
17
- requirement: &id001 !ruby/object:Gem::Requirement
18
- none: false
19
- requirements:
20
- - - ~>
21
- - !ruby/object:Gem::Version
22
- version: 3.0.6
23
- type: :runtime
11
+ date: 2020-05-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: coveralls
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
24
21
  prerelease: false
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
27
- name: rspec
28
- requirement: &id002 !ruby/object:Gem::Requirement
29
- none: false
30
- requirements:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
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:
31
38
  - - ">="
32
- - !ruby/object:Gem::Version
33
- version: "0"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
34
48
  type: :development
35
49
  prerelease: false
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
38
- name: jeweler
39
- requirement: &id003 !ruby/object:Gem::Requirement
40
- none: false
41
- requirements:
42
- - - ~>
43
- - !ruby/object:Gem::Version
44
- version: 1.5.2
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: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
45
62
  type: :development
46
63
  prerelease: false
47
- version_requirements: *id003
48
- - !ruby/object:Gem::Dependency
49
- name: rcov
50
- requirement: &id004 !ruby/object:Gem::Requirement
51
- none: false
52
- requirements:
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
53
66
  - - ">="
54
- - !ruby/object:Gem::Version
55
- version: "0"
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
56
76
  type: :development
57
77
  prerelease: false
58
- version_requirements: *id004
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
59
83
  description:
60
- email: chris@flatterline.com
84
+ email:
85
+ - squanderingtime@gmail.com
61
86
  executables: []
62
-
63
87
  extensions: []
64
-
65
- extra_rdoc_files:
66
- - README.rdoc
67
- files:
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
68
93
  - Gemfile
69
94
  - Gemfile.lock
70
95
  - README.rdoc
71
96
  - Rakefile
72
- - VERSION.yml
73
97
  - certificate_authority.gemspec
74
98
  - lib/certificate_authority.rb
75
99
  - lib/certificate_authority/certificate.rb
76
100
  - lib/certificate_authority/certificate_revocation_list.rb
101
+ - lib/certificate_authority/core_extensions.rb
77
102
  - lib/certificate_authority/distinguished_name.rb
78
103
  - lib/certificate_authority/extensions.rb
79
104
  - lib/certificate_authority/key_material.rb
80
105
  - lib/certificate_authority/ocsp_handler.rb
81
106
  - lib/certificate_authority/pkcs11_key_material.rb
107
+ - lib/certificate_authority/revocable.rb
82
108
  - lib/certificate_authority/serial_number.rb
83
109
  - lib/certificate_authority/signing_entity.rb
110
+ - lib/certificate_authority/signing_request.rb
111
+ - lib/certificate_authority/validations.rb
112
+ - lib/certificate_authority/version.rb
84
113
  - lib/tasks/certificate_authority.rake
85
- - spec/spec_helper.rb
86
- - spec/units/certificate_authority_spec.rb
87
- - spec/units/certificate_revocation_list_spec.rb
88
- - spec/units/certificate_spec.rb
89
- - spec/units/distinguished_name_spec.rb
90
- - spec/units/extensions_spec.rb
91
- - spec/units/key_material_spec.rb
92
- - spec/units/ocsp_handler_spec.rb
93
- - spec/units/serial_number_spec.rb
94
- - spec/units/signing_entity_spec.rb
95
- - spec/units/units_helper.rb
96
- homepage: http://github.com/cchandler/certificate_authority
97
- licenses:
114
+ homepage: https://github.com/cchandler/certificate_authority
115
+ licenses:
98
116
  - MIT
117
+ metadata:
118
+ homepage_uri: https://github.com/cchandler/certificate_authority
119
+ source_code_uri: https://github.com/cchandler/certificate_authority
99
120
  post_install_message:
100
121
  rdoc_options: []
101
-
102
- require_paths:
122
+ require_paths:
103
123
  - lib
104
- required_ruby_version: !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
107
126
  - - ">="
108
- - !ruby/object:Gem::Version
109
- hash: -4291817206657186993
110
- segments:
111
- - 0
112
- version: "0"
113
- required_rubygems_version: !ruby/object:Gem::Requirement
114
- none: false
115
- requirements:
127
+ - !ruby/object:Gem::Version
128
+ version: '2.4'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
116
131
  - - ">="
117
- - !ruby/object:Gem::Version
118
- version: "0"
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
119
134
  requirements: []
120
-
121
- rubyforge_project:
122
- rubygems_version: 1.7.2
135
+ rubygems_version: 3.1.2
123
136
  signing_key:
124
- specification_version: 3
137
+ specification_version: 4
125
138
  summary: Ruby gem for managing the core functions outlined in RFC-3280 for PKI
126
- test_files:
127
- - spec/spec_helper.rb
128
- - spec/units/certificate_authority_spec.rb
129
- - spec/units/certificate_revocation_list_spec.rb
130
- - spec/units/certificate_spec.rb
131
- - spec/units/distinguished_name_spec.rb
132
- - spec/units/extensions_spec.rb
133
- - spec/units/key_material_spec.rb
134
- - spec/units/ocsp_handler_spec.rb
135
- - spec/units/serial_number_spec.rb
136
- - spec/units/signing_entity_spec.rb
137
- - spec/units/units_helper.rb
139
+ test_files: []
@@ -1,5 +0,0 @@
1
- ---
2
- :major: 0
3
- :minor: 1
4
- :patch: 2
5
- :build:
@@ -1,4 +0,0 @@
1
- require 'rubygems'
2
- require 'rspec'
3
-
4
- require File.dirname(__FILE__) + '/../lib/certificate_authority'
@@ -1,4 +0,0 @@
1
- require File.dirname(__FILE__) + '/units_helper'
2
-
3
- describe CertificateAuthority do
4
- end
@@ -1,68 +0,0 @@
1
- require File.dirname(__FILE__) + '/units_helper'
2
-
3
- describe CertificateAuthority::CertificateRevocationList do
4
- before(:each) do
5
- @crl = CertificateAuthority::CertificateRevocationList.new
6
-
7
- @root_certificate = CertificateAuthority::Certificate.new
8
- @root_certificate.signing_entity = true
9
- @root_certificate.subject.common_name = "CRL Root"
10
- @root_certificate.key_material.generate_key
11
- @root_certificate.serial_number.number = 1
12
- @root_certificate.sign!
13
-
14
- @certificate = CertificateAuthority::Certificate.new
15
- @certificate.key_material.generate_key
16
- @certificate.subject.common_name = "http://bogusSite.com"
17
- @certificate.parent = @root_certificate
18
- @certificate.serial_number.number = 2
19
- @certificate.sign!
20
-
21
- @crl.parent = @root_certificate
22
- @certificate.revoked_at = Time.now
23
- end
24
-
25
- it "should accept a list of certificates" do
26
- @crl << @certificate
27
- end
28
-
29
- it "should complain if you add a certificate without a revocation time" do
30
- @certificate.revoked_at = nil
31
- lambda{ @crl << @certificate}.should raise_error
32
- end
33
-
34
- it "should have a 'parent' that will be responsible for signing" do
35
- @crl.parent = @root_certificate
36
- @crl.parent.should_not be_nil
37
- end
38
-
39
- it "should raise an error if you try and sign a CRL without attaching a parent" do
40
- @crl.parent = nil
41
- lambda { @crl.sign! }.should raise_error
42
- end
43
-
44
- it "should be able to generate a proper CRL" do
45
- @crl << @certificate
46
- lambda {@crl.to_pem}.should raise_error
47
- @crl.parent = @root_certificate
48
- @crl.sign!
49
- @crl.to_pem.should_not be_nil
50
- OpenSSL::X509::CRL.new(@crl.to_pem).should_not be_nil
51
- end
52
-
53
- describe "Next update" do
54
- it "should be able to set a 'next_update' value" do
55
- @crl.next_update = (60 * 60 * 10) # 10 Hours
56
- @crl.next_update.should_not be_nil
57
- end
58
-
59
- it "should throw an error if we try and sign up with a negative next_update" do
60
- @crl.sign!
61
- @crl.next_update = - (60 * 60 * 10)
62
- lambda{@crl.sign!}.should raise_error
63
- end
64
-
65
- end
66
-
67
-
68
- end