certificate_authority_sonian 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,59 @@
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
+ describe "from_openssl" do
39
+ before do
40
+ subject = "/CN=justincummins.name/L=on my laptop/ST=relaxed/C=as/O=programmer/OU=using this code"
41
+ @name = OpenSSL::X509::Name.parse subject
42
+ @dn = CertificateAuthority::DistinguishedName.from_openssl @name
43
+ end
44
+
45
+ it "should reject non Name objects" do
46
+ lambda { CertificateAuthority::DistinguishedName.from_openssl "Not a OpenSSL::X509::Name" }.should raise_error
47
+ end
48
+
49
+ [:common_name, :locality, :state, :country, :organization, :organizational_unit].each do |field|
50
+ it "should set the #{field} attribute" do
51
+ @dn.send(field).should_not be_nil
52
+ end
53
+ end
54
+
55
+ it "should create an equivalent object" do
56
+ @dn.to_x509_name.to_s.split('/').should =~ @name.to_s.split('/')
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,115 @@
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 for URIs" 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
+
53
+ it "should respond to :dns_names" do
54
+ subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
55
+ subjectAltName.respond_to?(:dns_names).should be_true
56
+ end
57
+
58
+ it "should require 'dns_names' to be an Array" do
59
+ subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
60
+ lambda {subjectAltName.dns_names = "not an array"}.should raise_error
61
+ end
62
+
63
+ it "should generate a proper OpenSSL extension string for DNS names" do
64
+ subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
65
+ subjectAltName.dns_names = ["localhost.altname.example.com"]
66
+ subjectAltName.to_s.should == "DNS:localhost.altname.example.com"
67
+
68
+ subjectAltName.dns_names = ["localhost.altname.example.com", "other.example.com"]
69
+ subjectAltName.to_s.should == "DNS:localhost.altname.example.com,DNS:other.example.com"
70
+ end
71
+
72
+ it "should respond to :ips" do
73
+ subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
74
+ subjectAltName.respond_to?(:ips).should be_true
75
+ end
76
+
77
+ it "should require 'ips' to be an Array" do
78
+ subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
79
+ lambda {subjectAltName.ips = "not an array"}.should raise_error
80
+ end
81
+
82
+ it "should generate a proper OpenSSL extension string for IPs" do
83
+ subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
84
+ subjectAltName.ips = ["1.2.3.4"]
85
+ subjectAltName.to_s.should == "IP:1.2.3.4"
86
+
87
+ subjectAltName.ips = ["1.2.3.4", "5.6.7.8"]
88
+ subjectAltName.to_s.should == "IP:1.2.3.4,IP:5.6.7.8"
89
+ end
90
+
91
+ it "should generate a proper OpenSSL extension string for URIs IPs and DNS names together" do
92
+ subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
93
+ subjectAltName.ips = ["1.2.3.4"]
94
+ subjectAltName.to_s.should == "IP:1.2.3.4"
95
+
96
+ subjectAltName.dns_names = ["localhost.altname.example.com"]
97
+ subjectAltName.to_s.should == "DNS:localhost.altname.example.com,IP:1.2.3.4"
98
+
99
+ subjectAltName.dns_names = ["localhost.altname.example.com", "other.example.com"]
100
+ subjectAltName.to_s.should == "DNS:localhost.altname.example.com,DNS:other.example.com,IP:1.2.3.4"
101
+
102
+ subjectAltName.ips = ["1.2.3.4", "5.6.7.8"]
103
+ subjectAltName.to_s.should == "DNS:localhost.altname.example.com,DNS:other.example.com,IP:1.2.3.4,IP:5.6.7.8"
104
+
105
+ subjectAltName.uris = ["http://localhost.altname.example.com"]
106
+ subjectAltName.to_s.should == "URI:http://localhost.altname.example.com,DNS:localhost.altname.example.com,DNS:other.example.com,IP:1.2.3.4,IP:5.6.7.8"
107
+
108
+ subjectAltName.uris = ["http://localhost.altname.example.com", "http://other.altname.example.com"]
109
+ subjectAltName.to_s.should == "URI:http://localhost.altname.example.com,URI:http://other.altname.example.com,DNS:localhost.altname.example.com,DNS:other.example.com,IP:1.2.3.4,IP:5.6.7.8"
110
+
111
+ end
112
+
113
+
114
+ end
115
+ end
@@ -0,0 +1,154 @@
1
+ require File.dirname(__FILE__) + '/units_helper'
2
+
3
+ describe CertificateAuthority::KeyMaterial do
4
+ [CertificateAuthority::MemoryKeyMaterial, CertificateAuthority::SigningRequestKeyMaterial].each do |key_material_class|
5
+ before do
6
+ @key_material = key_material_class.new
7
+ end
8
+
9
+ it "#{key_material_class} should know if a key is in memory or hardware" do
10
+ @key_material.is_in_hardware?.should_not be_nil
11
+ @key_material.is_in_memory?.should_not be_nil
12
+ end
13
+
14
+ it "should use memory by default" do
15
+ @key_material.is_in_memory?.should be_true
16
+ end
17
+ end
18
+ end
19
+
20
+ describe CertificateAuthority::MemoryKeyMaterial do
21
+ before(:each) do
22
+ @key_material = CertificateAuthority::MemoryKeyMaterial.new
23
+ end
24
+
25
+ it "should be able to generate an RSA key" do
26
+ @key_material.generate_key(1024).should_not be_nil
27
+ end
28
+
29
+ it "should generate a proper OpenSSL::PKey::RSA" do
30
+ @key_material.generate_key(1024).class.should == OpenSSL::PKey::RSA
31
+ end
32
+
33
+ it "should be able to specify the size of the modulus to generate" do
34
+ @key_material.generate_key(1024).should_not be_nil
35
+ end
36
+
37
+ describe "with generated key" do
38
+ before(:all) do
39
+ @key_material_in_memory = CertificateAuthority::MemoryKeyMaterial.new
40
+ @key_material_in_memory.generate_key(1024)
41
+ end
42
+
43
+ it "should be able to retrieve the private key" do
44
+ @key_material_in_memory.private_key.should_not be_nil
45
+ end
46
+
47
+ it "should be able to retrieve the public key" do
48
+ @key_material_in_memory.public_key.should_not be_nil
49
+ end
50
+ end
51
+
52
+ it "should not validate without public and private keys" do
53
+ @key_material.valid?.should be_false
54
+ @key_material.generate_key(1024)
55
+ @key_material.valid?.should be_true
56
+ pub = @key_material.public_key
57
+ @key_material.public_key = nil
58
+ @key_material.valid?.should be_false
59
+ @key_material.public_key = pub
60
+ @key_material.private_key = nil
61
+ @key_material.valid?.should be_false
62
+ end
63
+ end
64
+
65
+ describe CertificateAuthority::SigningRequestKeyMaterial do
66
+ before(:each) do
67
+ @request = OpenSSL::X509::Request.new <<CSR
68
+ -----BEGIN CERTIFICATE REQUEST-----
69
+ MIIBjTCB9wIBADBOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEU
70
+ MBIGA1UEBxMLQmVyc2Vya2VsZXkxFDASBgNVBAoTC0NlcnRzICdSIFVzMIGfMA0G
71
+ CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaGiBcv++581KYt6y2NNcUaZNPPeNZ0UkX
72
+ ujzZQQllx7PlYmsKTE6ZzfTUc0AJvDBIuACg03eagaEaBZtUFbsLkSOLJyYiIfF5
73
+ f9PuXImz2RDzBJQ/+u82gQAcvPhm94xK8jeNPcn0Ege7Y7SRK4YYonX+0ZveP02L
74
+ FjuEfrZcZQIDAQABoAAwDQYJKoZIhvcNAQEFBQADgYEAecOQz0RfnmSxxzOyHZ1e
75
+ Wo2hQqPOmkfIbvL2l1Ml+HybJQJn6OpLmeveyU48SI2M7UqeNkHtsogMljy3re4L
76
+ QlwK7lNd6SymdfSCPjUcdoLOaHolZXYNvCHltTc5skRHG7ti5yv4cu0ItIcCS0yp
77
+ 7L3maDEbTLsDdouHeFfbLWA=
78
+ -----END CERTIFICATE REQUEST-----
79
+ CSR
80
+ common_request = <<CSR
81
+ -----BEGIN CERTIFICATE REQUEST-----
82
+ MIICzzCCAbcCAQAwgYkxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczESMBAG
83
+ A1UEBwwJQXJsaW5ndG9uMQwwCgYDVQQKDANCYWgxCzAJBgNVBAsMAk5vMRswGQYD
84
+ VQQDDBJwemVyby5ib3VneW1hbi5jb20xHjAcBgkqhkiG9w0BCQEWD3RqQHJ1Ynlp
85
+ c3RzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL+UD2trMNFh
86
+ lR3utCWBO3i9/VVdz13OnsSrmrnKvVeB6wRUd1gtxJ6sTi70ywN1vJqC3OuiO53G
87
+ CPzqWDsaVhQy7wTYCY+6uRfI23pcZZG/sGOHVJAJw+zadyd5LDqh3khsaZHBx1VK
88
+ ZiRee09QAnN4kK1uxB5B1ZCE01GzS9ERck7thwlcH2mDMuUtMxXmtEcl8sSeCkZO
89
+ CJ9TH21Q90oryZH14+fkhIjDTmyXAtj7kOjyAEu6aD+kYd03Yk+5XWJUVdpuug9Y
90
+ ZX7oMd8dzg9wiWzveKWypQ23BxcUS9ejiZVhj0TE0UPAKIhTw/0QkWoNcHOkwh29
91
+ X4fdAFIR3gkCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4IBAQAqlbx13HtfXFJf2boC
92
+ IcGrjaY+rOh9rNrXiGN9+DCZciQhEi8ZpOdygwZ4oKE/QjnPX+Q2sm/xjyhqp62v
93
+ NZsIGR8jnu1L7c5Jik72W/E2Jz6WLb/dWcGn45pSgi1HvRm+SXTWCIpZYfUrA+A/
94
+ x1x4CgU+tBFXtgMGTbK6F+JoaGsBeBkYG95pYurgS9mo62r0Mau3qi68DFzcXCuR
95
+ IibGCcF9hys7LbqLLDob6i1Y9TQtw5f6ARE4SkA9TvWM3VPDxn6F+Qfg8TAj7r1q
96
+ vecFC7r3d0ySWkdsy+Snzvt0ruu5pOfaTRBQqrIKVeGpOIp7sOhBlExtl/unHkCZ
97
+ IpZl
98
+ -----END CERTIFICATE REQUEST-----
99
+ CSR
100
+ @openssl_req = OpenSSL::X509::Request.new common_request
101
+ @certificate = CertificateAuthority::Certificate.new
102
+ @certificate.serial_number.number = 1
103
+ @certificate.subject.common_name = "chrischandler.name"
104
+ @certificate.key_material.generate_key(1024)
105
+ @certificate.sign!
106
+ @key_material = CertificateAuthority::SigningRequestKeyMaterial.new @request
107
+ end
108
+
109
+ it "should generate from a CSR" do
110
+ @key_material.should_not be_nil
111
+ end
112
+
113
+ it "should be able to expose a public key" do
114
+ @key_material.public_key.should_not be_nil
115
+ end
116
+
117
+ it "should not have a private key" do
118
+ @key_material.private_key.should be_nil
119
+ end
120
+
121
+ it "should raise when signature does not verify" do
122
+ invalid = @request
123
+ invalid.public_key = OpenSSL::PKey::RSA.new 512
124
+ lambda { CertificateAuthority::SigningRequestKeyMaterial.new invalid }.should raise_error
125
+ end
126
+
127
+ it "should only accept valid OpenSSL requests" do
128
+ lambda { CertificateAuthority::SigningRequestKeyMaterial.new OpenSSL::X509::Request.new }.should raise_error(OpenSSL::X509::RequestError)
129
+ req = CertificateAuthority::SigningRequestKeyMaterial.new @openssl_req
130
+ req.csr.subject.should_not be_nil
131
+ end
132
+
133
+ it "should add a cert when signed by a root ca" do
134
+ csr = CertificateAuthority::SigningRequestKeyMaterial.new @openssl_req
135
+ signed_cert = csr.sign_and_certify(@certificate, @certificate.key_material.private_key, 555)
136
+ signed_cert.should_not be_nil
137
+ signed_cert.subject.to_x509_name.to_s.should == "/CN=pzero.bougyman.com/O=Bah/OU=No/ST=Texas/L=Arlington/C=US"
138
+ end
139
+
140
+ it "can sign an SPKAC SPKI and generate a certificate" do
141
+ spkac_raw = <<SPKAC
142
+ MIICQDCCASgwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVDEqzj21++aMWvN6zzwDXKKpR9g5hIeAPYqbUdaPFePhtz7R73l7fVxDeQZDQpQxTqts0/w0wEa/A1ehHCtAkDoTYzjwX8G0Gkb90poA156I8b4Cl1Q2veKbLsaOsMWItlXSU6HULQ5McfYfvEaPmIKiIr0UIFdzMDcy9TnY854w9TcQVvLJZcQkaM3dy/p9W4gg0a9hBJwwFUUR2UV/nEEi+++HbsOE46Z7Y3qoQhLrL4DNUrXUPDVeqac1SmNfKTA71QADbezWDfKi9habHHGXqk18i2Pl6uA2mpNPuSWnEHbQONgnfeoWZBvMWkwlolaBeWhGSmgcL/HqaRLlFAgMBAAEWADANBgkqhkiG9w0BAQQFAAOCAQEAp8wOvrl2QG9p1PS19dnrh4l0JWNAPB+d1kc64xUG6FAfGCKnOHzdDndTJfEERhWqFA0XL+mvKXCQsYKXkOuxYYmxJXZsdcCj7mOMhI2uMrEVd1ALFmG5WBW1Mo3nHHa/BX24fAOLv0+aGXYTz3oaMFydBw+XPZ26x9pO9LjlQQYGGyQRMpceWfej367KnR4a7IafDGBUI6OoWsx/7kQRIGkbmzi+dnU7HgpEExyz+uuxlUxrZqa13Ys8dBp62NBJWFanPl+AhMe8g/Li5aiERrMUbFtiXzOp48Si7J54fs+U3w0WoD9cdG5mN2Rn8Jog8azl+YC/XY987YGAi7Y8EQ==
143
+ SPKAC
144
+ spkac = OpenSSL::Netscape::SPKI.new spkac_raw
145
+ dn = CertificateAuthority::DistinguishedName.new
146
+ dn.common_name = "chrischandler.name"
147
+ csr = CertificateAuthority::SigningRequestKeyMaterial.new spkac
148
+ lambda { csr.sign_and_certify(@certificate, @certificate.key_material.private_key, 554) }.should raise_error(RuntimeError)
149
+ signed_cert = csr.sign_and_certify(@certificate, @certificate.key_material.private_key, 555, :dn => dn)
150
+ signed_cert.should_not be_nil
151
+ signed_cert.subject.to_x509_name.to_s.should == "/CN=chrischandler.name"
152
+ end
153
+
154
+ 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(1024)
11
+ @root_certificate.serial_number.number = 1
12
+ @root_certificate.sign!
13
+
14
+ @certificate = CertificateAuthority::Certificate.new
15
+ @certificate.key_material.generate_key(1024)
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,41 @@
1
+ require File.dirname(__FILE__) + '/units_helper'
2
+
3
+ ## Anything that requires crypto hardware needs to be tagged as 'pkcs11'
4
+ describe CertificateAuthority::Pkcs11KeyMaterial, :pkcs11 => true do
5
+ before(:each) do
6
+ @key_material_in_hardware = CertificateAuthority::Pkcs11KeyMaterial.new
7
+ @key_material_in_hardware.token_id = "46"
8
+ @key_material_in_hardware.pkcs11_lib = "/usr/lib/libeTPkcs11.so"
9
+ @key_material_in_hardware.openssl_pkcs11_engine_lib = "/usr/lib/engines/engine_pkcs11.so"
10
+ @key_material_in_hardware.pin = "11111111"
11
+ end
12
+
13
+ it "should identify as being in hardware", :pkcs11 => true do
14
+ @key_material_in_hardware.is_in_hardware?.should be_true
15
+ end
16
+
17
+ it "should return a Pkey ref if the private key is requested", :pkcs11 => true do
18
+ @key_material_in_hardware.private_key.class.should == OpenSSL::PKey::RSA
19
+ end
20
+
21
+ it "should return a Pkey ref if the public key is requested", :pkcs11 => true do
22
+ @key_material_in_hardware.public_key.class.should == OpenSSL::PKey::RSA
23
+ end
24
+
25
+ it "should accept an ID for on-token objects", :pkcs11 => true do
26
+ @key_material_in_hardware.respond_to?(:token_id).should be_true
27
+ end
28
+
29
+ it "should accept a path to a shared library for a PKCS11 driver", :pkcs11 => true do
30
+ @key_material_in_hardware.respond_to?(:pkcs11_lib).should be_true
31
+ end
32
+
33
+ it "should accept a path to OpenSSL's dynamic PKCS11 engine (provided by libengine-pkcs11-openssl)", :pkcs11 => true do
34
+ @key_material_in_hardware.respond_to?(:openssl_pkcs11_engine_lib).should be_true
35
+ end
36
+
37
+ it "should accept an optional PIN to authenticate to the token", :pkcs11 => true do
38
+ @key_material_in_hardware.respond_to?(:pin).should be_true
39
+ end
40
+
41
+ end