certificate_authority 0.1.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,38 @@
1
+ require File.dirname(__FILE__) + '/units_helper'
2
+
3
+ describe CertificateAuthority::DistinguishedName do
4
+ before(:each) do
5
+ @distinguished_name = CertificateAuthority::DistinguishedName.new
6
+ end
7
+
8
+ it "should provide the standard x.509 distinguished name common attributes" do
9
+ @distinguished_name.respond_to?(:cn).should be_true
10
+ @distinguished_name.respond_to?(:l).should be_true
11
+ @distinguished_name.respond_to?(:s).should be_true
12
+ @distinguished_name.respond_to?(:o).should be_true
13
+ @distinguished_name.respond_to?(:ou).should be_true
14
+ @distinguished_name.respond_to?(:c).should be_true
15
+ end
16
+
17
+ it "should provide human-readable equivalents to the distinguished name common attributes" do
18
+ @distinguished_name.respond_to?(:common_name).should be_true
19
+ @distinguished_name.respond_to?(:locality).should be_true
20
+ @distinguished_name.respond_to?(:state).should be_true
21
+ @distinguished_name.respond_to?(:organization).should be_true
22
+ @distinguished_name.respond_to?(:organizational_unit).should be_true
23
+ @distinguished_name.respond_to?(:country).should be_true
24
+ end
25
+
26
+ it "should require a common name" do
27
+ @distinguished_name.valid?.should be_false
28
+ @distinguished_name.errors.size.should == 1
29
+ @distinguished_name.common_name = "chrischandler.name"
30
+ @distinguished_name.valid?.should be_true
31
+ end
32
+
33
+ it "should be convertible to an OpenSSL::X509::Name" do
34
+ @distinguished_name.common_name = "chrischandler.name"
35
+ @distinguished_name.to_x509_name
36
+ end
37
+
38
+ end
@@ -0,0 +1,53 @@
1
+ require File.dirname(__FILE__) + '/units_helper'
2
+
3
+ describe CertificateAuthority::Extensions do
4
+ describe CertificateAuthority::Extensions::BasicContraints do
5
+ it "should only allow true/false" do
6
+ basic_constraints = CertificateAuthority::Extensions::BasicContraints.new
7
+ basic_constraints.valid?.should be_true
8
+ basic_constraints.ca = "moo"
9
+ basic_constraints.valid?.should be_false
10
+ end
11
+
12
+ it "should respond to :path_len" do
13
+ basic_constraints = CertificateAuthority::Extensions::BasicContraints.new
14
+ basic_constraints.respond_to?(:path_len).should be_true
15
+ end
16
+
17
+ it "should raise an error if :path_len isn't a non-negative integer" do
18
+ basic_constraints = CertificateAuthority::Extensions::BasicContraints.new
19
+ lambda {basic_constraints.path_len = "moo"}.should raise_error
20
+ lambda {basic_constraints.path_len = -1}.should raise_error
21
+ lambda {basic_constraints.path_len = 1.5}.should raise_error
22
+ end
23
+
24
+ it "should generate a proper OpenSSL extension string" do
25
+ basic_constraints = CertificateAuthority::Extensions::BasicContraints.new
26
+ basic_constraints.ca = true
27
+ basic_constraints.path_len = 2
28
+ basic_constraints.to_s.should == "CA:true,pathlen:2"
29
+ end
30
+ end
31
+
32
+ describe CertificateAuthority::Extensions::SubjectAlternativeName do
33
+ it "should respond to :uris" do
34
+ subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
35
+ subjectAltName.respond_to?(:uris).should be_true
36
+ end
37
+
38
+ it "should require 'uris' to be an Array" do
39
+ subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
40
+ lambda {subjectAltName.uris = "not an array"}.should raise_error
41
+ end
42
+
43
+ it "should generate a proper OpenSSL extension string" do
44
+ subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
45
+ subjectAltName.uris = ["http://localhost.altname.example.com"]
46
+ subjectAltName.to_s.should == "URI:http://localhost.altname.example.com"
47
+
48
+ subjectAltName.uris = ["http://localhost.altname.example.com", "http://other.example.com"]
49
+ subjectAltName.to_s.should == "URI:http://localhost.altname.example.com,URI:http://other.example.com"
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,96 @@
1
+ require File.dirname(__FILE__) + '/units_helper'
2
+
3
+ describe CertificateAuthority::MemoryKeyMaterial do
4
+ before(:each) do
5
+ @key_material = CertificateAuthority::MemoryKeyMaterial.new
6
+ end
7
+
8
+ it "should know if a key is in memory or hardware" do
9
+ @key_material.is_in_hardware?.should_not be_nil
10
+ @key_material.is_in_memory?.should_not be_nil
11
+ end
12
+
13
+ it "should use memory by default" do
14
+ @key_material.is_in_memory?.should be_true
15
+ end
16
+
17
+ it "should be able to generate an RSA key" do
18
+ @key_material.generate_key.should_not be_nil
19
+ end
20
+
21
+ it "should generate a proper OpenSSL::PKey::RSA" do
22
+ @key_material.generate_key.class.should == OpenSSL::PKey::RSA
23
+ end
24
+
25
+ it "should be able to specify the size of the modulus to generate" do
26
+ @key_material.generate_key(768).should_not be_nil
27
+ end
28
+
29
+ describe "in memory" do
30
+ before(:all) do
31
+ @key_material_in_memory = CertificateAuthority::MemoryKeyMaterial.new
32
+ @key_material_in_memory.generate_key
33
+ end
34
+
35
+ it "should be able to retrieve the private key" do
36
+ @key_material_in_memory.private_key.should_not be_nil
37
+ end
38
+
39
+ it "should be able to retrieve the public key" do
40
+ @key_material_in_memory.public_key.should_not be_nil
41
+ end
42
+ end
43
+
44
+ ## Anything that requires crypto hardware needs to be tagged as 'pkcs11'
45
+ describe "in hardware", :pkcs11 => true do
46
+ before(:each) do
47
+ @key_material_in_hardware = CertificateAuthority::Pkcs11KeyMaterial.new
48
+ @key_material_in_hardware.token_id = "46"
49
+ @key_material_in_hardware.pkcs11_lib = "/usr/lib/libeTPkcs11.so"
50
+ @key_material_in_hardware.openssl_pkcs11_engine_lib = "/usr/lib/engines/engine_pkcs11.so"
51
+ @key_material_in_hardware.pin = "11111111"
52
+ end
53
+
54
+ it "should identify as being in hardware", :pkcs11 => true do
55
+ @key_material_in_hardware.is_in_hardware?.should be_true
56
+ end
57
+
58
+ it "should return a Pkey ref if the private key is requested", :pkcs11 => true do
59
+ @key_material_in_hardware.private_key.class.should == OpenSSL::PKey::RSA
60
+ end
61
+
62
+ it "should return a Pkey ref if the private key is requested", :pkcs11 => true do
63
+ @key_material_in_hardware.public_key.class.should == OpenSSL::PKey::RSA
64
+ end
65
+
66
+ it "should accept an ID for on-token objects", :pkcs11 => true do
67
+ @key_material_in_hardware.respond_to?(:token_id).should be_true
68
+ end
69
+
70
+ it "should accept a path to a shared library for a PKCS11 driver", :pkcs11 => true do
71
+ @key_material_in_hardware.respond_to?(:pkcs11_lib).should be_true
72
+ end
73
+
74
+ it "should accept a path to OpenSSL's dynamic PKCS11 engine (provided by libengine-pkcs11-openssl)", :pkcs11 => true do
75
+ @key_material_in_hardware.respond_to?(:openssl_pkcs11_engine_lib).should be_true
76
+ end
77
+
78
+ it "should accept an optional PIN to authenticate to the token", :pkcs11 => true do
79
+ @key_material_in_hardware.respond_to?(:pin).should be_true
80
+ end
81
+
82
+ end
83
+
84
+ it "not validate without public and private keys" do
85
+ @key_material.valid?.should be_false
86
+ @key_material.generate_key
87
+ @key_material.valid?.should be_true
88
+ pub = @key_material.public_key
89
+ @key_material.public_key = nil
90
+ @key_material.valid?.should be_false
91
+ @key_material.public_key = pub
92
+ @key_material.private_key = nil
93
+ @key_material.valid?.should be_false
94
+ end
95
+
96
+ end
@@ -0,0 +1,104 @@
1
+ require File.dirname(__FILE__) + '/units_helper'
2
+
3
+ describe CertificateAuthority::OCSPHandler do
4
+ before(:each) do
5
+ @ocsp_handler = CertificateAuthority::OCSPHandler.new
6
+
7
+ @root_certificate = CertificateAuthority::Certificate.new
8
+ @root_certificate.signing_entity = true
9
+ @root_certificate.subject.common_name = "OCSP 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://questionablesite.com"
17
+ @certificate.parent = @root_certificate
18
+ @certificate.serial_number.number = 2
19
+ @certificate.sign!
20
+
21
+ @ocsp_request = OpenSSL::OCSP::Request.new
22
+ openssl_cert_issuer = OpenSSL::X509::Certificate.new(@root_certificate.to_pem)
23
+ openssl_cert_subject = OpenSSL::X509::Certificate.new(@certificate.to_pem)
24
+
25
+ cert_id = OpenSSL::OCSP::CertificateId.new(openssl_cert_subject, openssl_cert_issuer)
26
+ @ocsp_request.add_certid(cert_id)
27
+ @ocsp_handler.ocsp_request = @ocsp_request.to_der
28
+ end
29
+
30
+ it "should be able to accept an OCSP Request" do
31
+ @ocsp_handler.ocsp_request = @ocsp_request
32
+ @ocsp_handler.ocsp_request.should_not be_nil
33
+ end
34
+
35
+ it "should raise an error if you try and extract certificates without a raw request" do
36
+ @ocsp_handler.extract_certificate_serials
37
+ @ocsp_handler.ocsp_request = nil
38
+ lambda {@ocsp_handler.extract_certificate_serials}.should raise_error
39
+ end
40
+
41
+ it "should return a hash of extracted certificates from OCSP requests" do
42
+ result = @ocsp_handler.extract_certificate_serials
43
+ result.size.should == 1
44
+ end
45
+
46
+ it "should be able to generate an OCSP response" do
47
+ @ocsp_handler.extract_certificate_serials
48
+ @ocsp_handler << @certificate
49
+ @ocsp_handler.parent = @root_certificate
50
+ @ocsp_handler.response
51
+ end
52
+
53
+ it "should require a 'parent' entity for signing" do
54
+ @ocsp_handler.parent = @root_certificate
55
+ @ocsp_handler.parent.should_not be_nil
56
+ end
57
+
58
+ it "should raise an error if you ask for the signed OCSP response without generating it" do
59
+ @ocsp_handler.extract_certificate_serials
60
+ @ocsp_handler << @certificate
61
+ @ocsp_handler.parent = @root_certificate
62
+ lambda { @ocsp_handler.to_der }.should raise_error
63
+ @ocsp_handler.response
64
+ @ocsp_handler.to_der.should_not be_nil
65
+ end
66
+
67
+ it "should raise an error if you generate a response without adding all certificates in request" do
68
+ @ocsp_handler.extract_certificate_serials
69
+ @ocsp_handler.parent = @root_certificate
70
+ lambda { @ocsp_handler.response }.should raise_error
71
+ end
72
+
73
+ it "should raise an error if you generate a response without adding a parent signing entity" do
74
+ @ocsp_handler.extract_certificate_serials
75
+ @ocsp_handler << @certificate
76
+ lambda { @ocsp_handler.response }.should raise_error
77
+ end
78
+
79
+ describe "Response" do
80
+ before(:each) do
81
+ @ocsp_handler.extract_certificate_serials
82
+ @ocsp_handler << @certificate
83
+ @ocsp_handler.parent = @root_certificate
84
+ @ocsp_handler.response
85
+
86
+ @openssl_ocsp_response = OpenSSL::OCSP::Response.new(@ocsp_handler.to_der)
87
+ end
88
+
89
+ it "should have a correct status/status string" do
90
+ @openssl_ocsp_response.status_string.should == "successful"
91
+ @openssl_ocsp_response.status.should == 0
92
+ end
93
+
94
+ it "should have an embedded BasicResponse with certificate statuses" do
95
+ # [#<OpenSSL::OCSP::CertificateId:0x000001020ecad8>, 0, 1, nil, 2011-04-15 23:29:47 UTC, 2011-04-15 23:30:17 UTC, []]
96
+ @openssl_ocsp_response.basic.status.first[1].should == 0 # Everything is OK
97
+ end
98
+
99
+ it "should have a next_update time" do
100
+ @openssl_ocsp_response.basic.status.first[5].should_not be_nil
101
+ @openssl_ocsp_response.basic.status.first[5].class.should == Time
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/units_helper'
2
+
3
+ describe CertificateAuthority::SerialNumber do
4
+ before(:each) do
5
+ @serial_number = CertificateAuthority::SerialNumber.new
6
+ end
7
+
8
+ it "should support basic integer serial numbers", :rfc3280 => true do
9
+ @serial_number.number = 25
10
+ @serial_number.should be_valid
11
+ @serial_number.number = "abc"
12
+ @serial_number.should_not be_valid
13
+ end
14
+
15
+ it "should not allow negative serial numbers", :rfc3280 => true do
16
+ @serial_number.number = -5
17
+ @serial_number.should_not be_valid
18
+ end
19
+
20
+ end
@@ -0,0 +1,4 @@
1
+ require File.dirname(__FILE__) + '/units_helper'
2
+
3
+ describe CertificateAuthority::SigningEntity do
4
+ end
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: certificate_authority
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.1
6
+ platform: ruby
7
+ authors:
8
+ - Chris Chandler
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-20 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: "0"
23
+ type: :runtime
24
+ 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:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ type: :runtime
35
+ 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
45
+ type: :runtime
46
+ 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:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: activemodel
61
+ requirement: &id005 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - "="
65
+ - !ruby/object:Gem::Version
66
+ version: 3.0.6
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *id005
70
+ description:
71
+ email: chris@flatterline.com
72
+ executables: []
73
+
74
+ extensions: []
75
+
76
+ extra_rdoc_files:
77
+ - README.rdoc
78
+ files:
79
+ - Gemfile
80
+ - Gemfile.lock
81
+ - README.rdoc
82
+ - Rakefile
83
+ - VERSION.yml
84
+ - certificate_authority.gemspec
85
+ - lib/certificate_authority.rb
86
+ - lib/certificate_authority/certificate.rb
87
+ - lib/certificate_authority/certificate_revocation_list.rb
88
+ - lib/certificate_authority/distinguished_name.rb
89
+ - lib/certificate_authority/extensions.rb
90
+ - lib/certificate_authority/key_material.rb
91
+ - lib/certificate_authority/ocsp_handler.rb
92
+ - lib/certificate_authority/pkcs11_key_material.rb
93
+ - lib/certificate_authority/serial_number.rb
94
+ - lib/certificate_authority/signing_entity.rb
95
+ - lib/tasks/certificate_authority.rake
96
+ - spec/spec_helper.rb
97
+ - spec/units/certificate_authority_spec.rb
98
+ - spec/units/certificate_revocation_list_spec.rb
99
+ - spec/units/certificate_spec.rb
100
+ - spec/units/distinguished_name_spec.rb
101
+ - spec/units/extensions_spec.rb
102
+ - spec/units/key_material_spec.rb
103
+ - spec/units/ocsp_handler_spec.rb
104
+ - spec/units/serial_number_spec.rb
105
+ - spec/units/signing_entity_spec.rb
106
+ - spec/units/units_helper.rb
107
+ homepage: http://github.com/cchandler/certificate_authority
108
+ licenses:
109
+ - MIT
110
+ post_install_message:
111
+ rdoc_options: []
112
+
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ hash: -1515713382704752763
121
+ segments:
122
+ - 0
123
+ version: "0"
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: "0"
130
+ requirements: []
131
+
132
+ rubyforge_project:
133
+ rubygems_version: 1.7.2
134
+ signing_key:
135
+ specification_version: 3
136
+ summary: Ruby gem for managing the core functions outlined in RFC-3280 for PKI
137
+ test_files:
138
+ - spec/spec_helper.rb
139
+ - spec/units/certificate_authority_spec.rb
140
+ - spec/units/certificate_revocation_list_spec.rb
141
+ - spec/units/certificate_spec.rb
142
+ - spec/units/distinguished_name_spec.rb
143
+ - spec/units/extensions_spec.rb
144
+ - spec/units/key_material_spec.rb
145
+ - spec/units/ocsp_handler_spec.rb
146
+ - spec/units/serial_number_spec.rb
147
+ - spec/units/signing_entity_spec.rb
148
+ - spec/units/units_helper.rb