certificate_authority 0.1.1

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