r509 0.8
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.
- data/README.md +447 -0
- data/Rakefile +38 -0
- data/bin/r509 +96 -0
- data/bin/r509-parse +35 -0
- data/doc/R509.html +154 -0
- data/doc/R509/Cert.html +3954 -0
- data/doc/R509/Cert/Extensions.html +360 -0
- data/doc/R509/Cert/Extensions/AuthorityInfoAccess.html +391 -0
- data/doc/R509/Cert/Extensions/AuthorityKeyIdentifier.html +148 -0
- data/doc/R509/Cert/Extensions/BasicConstraints.html +482 -0
- data/doc/R509/Cert/Extensions/CrlDistributionPoints.html +316 -0
- data/doc/R509/Cert/Extensions/ExtendedKeyUsage.html +780 -0
- data/doc/R509/Cert/Extensions/KeyUsage.html +1230 -0
- data/doc/R509/Cert/Extensions/SubjectAlternativeName.html +467 -0
- data/doc/R509/Cert/Extensions/SubjectKeyIdentifier.html +216 -0
- data/doc/R509/CertificateAuthority.html +126 -0
- data/doc/R509/CertificateAuthority/Signer.html +855 -0
- data/doc/R509/Config.html +127 -0
- data/doc/R509/Config/CaConfig.html +2144 -0
- data/doc/R509/Config/CaConfigPool.html +599 -0
- data/doc/R509/Config/CaProfile.html +656 -0
- data/doc/R509/Config/SubjectItemPolicy.html +578 -0
- data/doc/R509/Crl.html +126 -0
- data/doc/R509/Crl/Administrator.html +2077 -0
- data/doc/R509/Crl/Parser.html +1224 -0
- data/doc/R509/Csr.html +2248 -0
- data/doc/R509/IOHelpers.html +564 -0
- data/doc/R509/MessageDigest.html +396 -0
- data/doc/R509/NameSanitizer.html +319 -0
- data/doc/R509/Ocsp.html +128 -0
- data/doc/R509/Ocsp/Request.html +126 -0
- data/doc/R509/Ocsp/Request/Nonce.html +160 -0
- data/doc/R509/Ocsp/Response.html +837 -0
- data/doc/R509/OidMapper.html +393 -0
- data/doc/R509/PrivateKey.html +1647 -0
- data/doc/R509/R509Error.html +134 -0
- data/doc/R509/Spki.html +1424 -0
- data/doc/R509/Subject.html +836 -0
- data/doc/R509/Validity.html +160 -0
- data/doc/R509/Validity/Checker.html +320 -0
- data/doc/R509/Validity/DefaultChecker.html +283 -0
- data/doc/R509/Validity/DefaultWriter.html +330 -0
- data/doc/R509/Validity/Status.html +561 -0
- data/doc/R509/Validity/Writer.html +394 -0
- data/doc/_index.html +501 -0
- data/doc/class_list.html +53 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +328 -0
- data/doc/file.README.html +534 -0
- data/doc/file.r509.html +149 -0
- data/doc/file_list.html +58 -0
- data/doc/frames.html +28 -0
- data/doc/index.html +534 -0
- data/doc/js/app.js +208 -0
- data/doc/js/full_list.js +173 -0
- data/doc/js/jquery.js +4 -0
- data/doc/methods_list.html +1932 -0
- data/doc/top-level-namespace.html +112 -0
- data/lib/r509.rb +22 -0
- data/lib/r509/cert.rb +414 -0
- data/lib/r509/cert/extensions.rb +309 -0
- data/lib/r509/certificateauthority.rb +290 -0
- data/lib/r509/config.rb +407 -0
- data/lib/r509/crl.rb +379 -0
- data/lib/r509/csr.rb +324 -0
- data/lib/r509/exceptions.rb +5 -0
- data/lib/r509/io_helpers.rb +52 -0
- data/lib/r509/messagedigest.rb +49 -0
- data/lib/r509/ocsp.rb +85 -0
- data/lib/r509/oidmapper.rb +32 -0
- data/lib/r509/privatekey.rb +185 -0
- data/lib/r509/spki.rb +112 -0
- data/lib/r509/subject.rb +133 -0
- data/lib/r509/validity.rb +92 -0
- data/lib/r509/version.rb +4 -0
- data/r509.yaml +73 -0
- data/spec/cert/extensions_spec.rb +632 -0
- data/spec/cert_spec.rb +321 -0
- data/spec/certificate_authority_spec.rb +260 -0
- data/spec/config_spec.rb +349 -0
- data/spec/crl_spec.rb +215 -0
- data/spec/csr_spec.rb +302 -0
- data/spec/fixtures.rb +233 -0
- data/spec/fixtures/cert1.der +0 -0
- data/spec/fixtures/cert1.pem +24 -0
- data/spec/fixtures/cert1_public_key_modulus.txt +1 -0
- data/spec/fixtures/cert3.p12 +0 -0
- data/spec/fixtures/cert3.pem +28 -0
- data/spec/fixtures/cert3_key.pem +27 -0
- data/spec/fixtures/cert3_key_des3.pem +30 -0
- data/spec/fixtures/cert4.pem +14 -0
- data/spec/fixtures/cert5.pem +30 -0
- data/spec/fixtures/cert6.pem +26 -0
- data/spec/fixtures/cert_expired.pem +26 -0
- data/spec/fixtures/cert_not_yet_valid.pem +26 -0
- data/spec/fixtures/cert_san.pem +27 -0
- data/spec/fixtures/cert_san2.pem +22 -0
- data/spec/fixtures/config_pool_test_minimal.yaml +15 -0
- data/spec/fixtures/config_test.yaml +41 -0
- data/spec/fixtures/config_test_engine_key.yaml +7 -0
- data/spec/fixtures/config_test_engine_no_key_name.yaml +6 -0
- data/spec/fixtures/config_test_minimal.yaml +7 -0
- data/spec/fixtures/config_test_password.yaml +7 -0
- data/spec/fixtures/config_test_various.yaml +100 -0
- data/spec/fixtures/crl_list_file.txt +1 -0
- data/spec/fixtures/crl_with_reason.pem +17 -0
- data/spec/fixtures/csr1.der +0 -0
- data/spec/fixtures/csr1.pem +17 -0
- data/spec/fixtures/csr1_key.der +0 -0
- data/spec/fixtures/csr1_key.pem +27 -0
- data/spec/fixtures/csr1_key_encrypted_des3.pem +30 -0
- data/spec/fixtures/csr1_newlines.pem +32 -0
- data/spec/fixtures/csr1_no_begin_end.pem +15 -0
- data/spec/fixtures/csr1_public_key_modulus.txt +1 -0
- data/spec/fixtures/csr2.pem +15 -0
- data/spec/fixtures/csr2_key.pem +27 -0
- data/spec/fixtures/csr3.pem +16 -0
- data/spec/fixtures/csr4.pem +25 -0
- data/spec/fixtures/csr_dsa.pem +15 -0
- data/spec/fixtures/csr_invalid_signature.pem +13 -0
- data/spec/fixtures/dsa_key.pem +20 -0
- data/spec/fixtures/key4.pem +27 -0
- data/spec/fixtures/key4_encrypted_des3.pem +30 -0
- data/spec/fixtures/missing_key_identifier_ca.cer +21 -0
- data/spec/fixtures/missing_key_identifier_ca.key +27 -0
- data/spec/fixtures/ocsptest.r509.local.pem +27 -0
- data/spec/fixtures/ocsptest.r509.local_ocsp_request.der +0 -0
- data/spec/fixtures/ocsptest2.r509.local.pem +27 -0
- data/spec/fixtures/second_ca.cer +26 -0
- data/spec/fixtures/second_ca.key +27 -0
- data/spec/fixtures/spkac.der +0 -0
- data/spec/fixtures/spkac.txt +1 -0
- data/spec/fixtures/spkac_dsa.txt +1 -0
- data/spec/fixtures/stca.pem +22 -0
- data/spec/fixtures/stca_ocsp_request.der +0 -0
- data/spec/fixtures/stca_ocsp_response.der +0 -0
- data/spec/fixtures/test1.csr +17 -0
- data/spec/fixtures/test_ca.cer +22 -0
- data/spec/fixtures/test_ca.key +28 -0
- data/spec/fixtures/test_ca.p12 +0 -0
- data/spec/fixtures/test_ca_des3.key +30 -0
- data/spec/fixtures/test_ca_ocsp.cer +26 -0
- data/spec/fixtures/test_ca_ocsp.key +27 -0
- data/spec/fixtures/test_ca_ocsp.p12 +0 -0
- data/spec/fixtures/test_ca_ocsp_chain.txt +48 -0
- data/spec/fixtures/test_ca_ocsp_response.der +0 -0
- data/spec/fixtures/test_ca_subroot.cer +26 -0
- data/spec/fixtures/test_ca_subroot.key +27 -0
- data/spec/fixtures/test_ca_subroot_ocsp.cer +25 -0
- data/spec/fixtures/test_ca_subroot_ocsp.key +27 -0
- data/spec/fixtures/test_ca_subroot_ocsp_response.der +0 -0
- data/spec/fixtures/unknown_oid.csr +17 -0
- data/spec/message_digest_spec.rb +89 -0
- data/spec/ocsp_spec.rb +111 -0
- data/spec/oid_mapper_spec.rb +31 -0
- data/spec/privatekey_spec.rb +198 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/spki_spec.rb +157 -0
- data/spec/subject_spec.rb +203 -0
- data/spec/validity_spec.rb +98 -0
- metadata +257 -0
data/spec/config_spec.rb
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'r509/config'
|
|
3
|
+
require 'r509/exceptions'
|
|
4
|
+
|
|
5
|
+
describe R509::Config::CaConfigPool do
|
|
6
|
+
context "defined manually" do
|
|
7
|
+
it "has no configs" do
|
|
8
|
+
pool = R509::Config::CaConfigPool.new({})
|
|
9
|
+
|
|
10
|
+
pool["first"].should == nil
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "has one config" do
|
|
14
|
+
config = R509::Config::CaConfig.new(
|
|
15
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
16
|
+
:profiles => { "first_profile" => R509::Config::CaProfile.new }
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
pool = R509::Config::CaConfigPool.new({
|
|
20
|
+
"first" => config
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
pool["first"].should == config
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context "all configs" do
|
|
28
|
+
it "no configs" do
|
|
29
|
+
pool = R509::Config::CaConfigPool.new({})
|
|
30
|
+
pool.all.should == []
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "one config" do
|
|
34
|
+
config = R509::Config::CaConfig.new(
|
|
35
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
36
|
+
:profiles => { "first_profile" => R509::Config::CaProfile.new }
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
pool = R509::Config::CaConfigPool.new({
|
|
40
|
+
"first" => config
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
pool.all.should == [config]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "two configs" do
|
|
47
|
+
config1 = R509::Config::CaConfig.new(
|
|
48
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
49
|
+
:profiles => { "first_profile" => R509::Config::CaProfile.new }
|
|
50
|
+
)
|
|
51
|
+
config2 = R509::Config::CaConfig.new(
|
|
52
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
53
|
+
:profiles => { "first_profile" => R509::Config::CaProfile.new }
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
pool = R509::Config::CaConfigPool.new({
|
|
57
|
+
"first" => config1,
|
|
58
|
+
"second" => config2
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
pool.all.size.should == 2
|
|
62
|
+
pool.all.include?(config1).should == true
|
|
63
|
+
pool.all.include?(config2).should == true
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context "loaded from YAML" do
|
|
68
|
+
it "should load two configs" do
|
|
69
|
+
pool = R509::Config::CaConfigPool.from_yaml("certificate_authorities", File.read("#{File.dirname(__FILE__)}/fixtures/config_pool_test_minimal.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"})
|
|
70
|
+
|
|
71
|
+
pool.names.should include("test_ca", "second_ca")
|
|
72
|
+
|
|
73
|
+
pool["test_ca"].should_not == nil
|
|
74
|
+
pool["test_ca"].num_profiles.should == 0
|
|
75
|
+
pool["second_ca"].should_not == nil
|
|
76
|
+
pool["second_ca"].num_profiles.should == 0
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe R509::Config::CaConfig do
|
|
82
|
+
before :each do
|
|
83
|
+
@config = R509::Config::CaConfig.new(
|
|
84
|
+
:ca_cert => TestFixtures.test_ca_cert
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
subject {@config}
|
|
89
|
+
|
|
90
|
+
its(:message_digest) {should == "SHA1"}
|
|
91
|
+
its(:crl_validity_hours) {should == 168}
|
|
92
|
+
its(:ocsp_validity_hours) {should == 168}
|
|
93
|
+
its(:ocsp_start_skew_seconds) {should == 3600}
|
|
94
|
+
its(:cdp_location) {should be_nil}
|
|
95
|
+
its(:ocsp_location) {should be_nil}
|
|
96
|
+
its(:num_profiles) {should == 0}
|
|
97
|
+
|
|
98
|
+
it "should have the proper CA cert" do
|
|
99
|
+
@config.ca_cert.to_pem.should == TestFixtures.test_ca_cert.to_pem
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should have the proper CA key" do
|
|
103
|
+
@config.ca_cert.key.to_pem.should == TestFixtures.test_ca_cert.key.to_pem
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "raises an error if you don't pass :ca_cert" do
|
|
107
|
+
expect { R509::Config::CaConfig.new(:crl_validity_hours => 2) }.to raise_error ArgumentError, 'Config object requires that you pass :ca_cert'
|
|
108
|
+
end
|
|
109
|
+
it "raises an error if :ca_cert is not of type R509::Cert" do
|
|
110
|
+
expect { R509::Config::CaConfig.new(:ca_cert => 'not a cert, and not right type') }.to raise_error ArgumentError, ':ca_cert must be of type R509::Cert'
|
|
111
|
+
end
|
|
112
|
+
it "loads the config even if :ca_cert does not contain a private key" do
|
|
113
|
+
config = R509::Config::CaConfig.new( :ca_cert => R509::Cert.new( :cert => TestFixtures::TEST_CA_CERT) )
|
|
114
|
+
config.ca_cert.subject.to_s.should_not be_nil
|
|
115
|
+
end
|
|
116
|
+
it "raises an error if :ocsp_cert that is not R509::Cert" do
|
|
117
|
+
expect { R509::Config::CaConfig.new(:ca_cert => TestFixtures.test_ca_cert, :ocsp_cert => "not a cert") }.to raise_error ArgumentError, ':ocsp_cert, if provided, must be of type R509::Cert'
|
|
118
|
+
end
|
|
119
|
+
it "raises an error if :ocsp_cert does not contain a private key" do
|
|
120
|
+
expect { R509::Config::CaConfig.new( :ca_cert => TestFixtures.test_ca_cert, :ocsp_cert => R509::Cert.new( :cert => TestFixtures::TEST_CA_CERT) ) }.to raise_error ArgumentError, ':ocsp_cert must contain a private key, not just a certificate'
|
|
121
|
+
end
|
|
122
|
+
it "returns the correct cert object on #ocsp_cert if none is specified" do
|
|
123
|
+
@config.ocsp_cert.should == @config.ca_cert
|
|
124
|
+
end
|
|
125
|
+
it "returns the correct cert object on #ocsp_cert if an ocsp_cert was specified" do
|
|
126
|
+
ocsp_cert = R509::Cert.new(
|
|
127
|
+
:cert => TestFixtures::TEST_CA_OCSP_CERT,
|
|
128
|
+
:key => TestFixtures::TEST_CA_OCSP_KEY
|
|
129
|
+
)
|
|
130
|
+
config = R509::Config::CaConfig.new(
|
|
131
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
132
|
+
:ocsp_cert => ocsp_cert
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
config.ocsp_cert.should == ocsp_cert
|
|
136
|
+
end
|
|
137
|
+
it "fails to specify a non-Config::CaProfile as the profile" do
|
|
138
|
+
config = R509::Config::CaConfig.new(
|
|
139
|
+
:ca_cert => TestFixtures.test_ca_cert
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
expect{ config.set_profile("bogus", "not a Config::CaProfile")}.to raise_error TypeError
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "shouldn't let you specify a profile that's not a Config::CaProfile, on instantiation" do
|
|
146
|
+
expect{ R509::Config::CaConfig.new(
|
|
147
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
148
|
+
:profiles => { "first_profile" => "not a Config::CaProfile" }
|
|
149
|
+
) }.to raise_error TypeError
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "can specify a single profile" do
|
|
153
|
+
first_profile = R509::Config::CaProfile.new
|
|
154
|
+
|
|
155
|
+
config = R509::Config::CaConfig.new(
|
|
156
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
157
|
+
:profiles => { "first_profile" => first_profile }
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
config.profile("first_profile").should == first_profile
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it "raises an error if you specify an invalid profile" do
|
|
164
|
+
first_profile = R509::Config::CaProfile.new
|
|
165
|
+
|
|
166
|
+
config = R509::Config::CaConfig.new(
|
|
167
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
168
|
+
:profiles => { "first_profile" => first_profile }
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
expect { config.profile("non-existent-profile") }.to raise_error(R509::R509Error, "unknown profile 'non-existent-profile'")
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "should load YAML" do
|
|
175
|
+
config = R509::Config::CaConfig.from_yaml("test_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"})
|
|
176
|
+
config.crl_validity_hours.should == 72
|
|
177
|
+
config.ocsp_validity_hours.should == 96
|
|
178
|
+
config.message_digest.should == "SHA1"
|
|
179
|
+
config.num_profiles.should == 3
|
|
180
|
+
end
|
|
181
|
+
it "loads OCSP cert/key from yaml" do
|
|
182
|
+
config = R509::Config::CaConfig.from_yaml("ocsp_delegate_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_various.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"})
|
|
183
|
+
config.ocsp_cert.has_private_key?.should == true
|
|
184
|
+
config.ocsp_cert.subject.to_s.should == "/C=US/ST=Illinois/L=Chicago/O=r509 LLC/CN=r509 OCSP Signer"
|
|
185
|
+
end
|
|
186
|
+
it "loads OCSP pkcs12 from yaml" do
|
|
187
|
+
config = R509::Config::CaConfig.from_yaml("ocsp_pkcs12_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_various.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"})
|
|
188
|
+
config.ocsp_cert.has_private_key?.should == true
|
|
189
|
+
config.ocsp_cert.subject.to_s.should == "/C=US/ST=Illinois/L=Chicago/O=r509 LLC/CN=r509 OCSP Signer"
|
|
190
|
+
end
|
|
191
|
+
it "loads OCSP cert/key in engine from yaml" do
|
|
192
|
+
#most of this code path is tested by loading ca_cert engine.
|
|
193
|
+
#look there for the extensive doubling
|
|
194
|
+
expect { R509::Config::CaConfig.from_yaml("ocsp_engine_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_various.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"}) }.to raise_error(R509::R509Error,"You must supply a key_name with an engine")
|
|
195
|
+
end
|
|
196
|
+
it "loads OCSP chain from yaml" do
|
|
197
|
+
config = R509::Config::CaConfig.from_yaml("ocsp_chain_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_various.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"})
|
|
198
|
+
config.ocsp_chain.size.should == 2
|
|
199
|
+
config.ocsp_chain[0].kind_of?(OpenSSL::X509::Certificate).should == true
|
|
200
|
+
config.ocsp_chain[1].kind_of?(OpenSSL::X509::Certificate).should == true
|
|
201
|
+
end
|
|
202
|
+
it "should load subject_item_policy from yaml (if present)" do
|
|
203
|
+
config = R509::Config::CaConfig.from_yaml("test_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"})
|
|
204
|
+
config.profile("server").subject_item_policy.should be_nil
|
|
205
|
+
config.profile("server_with_subject_item_policy").subject_item_policy.optional.should include("O","OU")
|
|
206
|
+
config.profile("server_with_subject_item_policy").subject_item_policy.required.should include("CN","ST","C")
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
it "should load YAML which only has a CA Cert and Key defined" do
|
|
210
|
+
config = R509::Config::CaConfig.from_yaml("test_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_minimal.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"})
|
|
211
|
+
config.num_profiles.should == 0
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it "should load YAML which has CA cert and key with password" do
|
|
215
|
+
expect { R509::Config::CaConfig.from_yaml("password_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_password.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"}) }.to_not raise_error
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it "should load YAML which has a PKCS12 with password" do
|
|
219
|
+
expect { R509::Config::CaConfig.from_yaml("pkcs12_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_various.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"}) }.to_not raise_error
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it "raises error on YAML with pkcs12 and key" do
|
|
223
|
+
expect { R509::Config::CaConfig.from_yaml("pkcs12_key_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_various.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"}) }.to raise_error(R509::R509Error, "You can't specify both pkcs12 and key")
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it "raises error on YAML with pkcs12 and cert" do
|
|
227
|
+
expect { R509::Config::CaConfig.from_yaml("pkcs12_cert_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_various.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"}) }.to raise_error(R509::R509Error, "You can't specify both pkcs12 and cert")
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it "raises error on YAML with pkcs12 and engine" do
|
|
231
|
+
expect { R509::Config::CaConfig.from_yaml("pkcs12_engine_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_various.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"}) }.to raise_error(R509::R509Error, "You can't specify both engine and pkcs12")
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it "loads config with cert and no key (useful in certain cases)" do
|
|
235
|
+
config = R509::Config::CaConfig.from_yaml("cert_no_key_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_various.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"})
|
|
236
|
+
config.ca_cert.subject.to_s.should_not be_nil
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it "should load YAML which has an engine" do
|
|
240
|
+
#i can test this, it's just gonna take a whole lot of floorin' it!
|
|
241
|
+
conf = double("conf")
|
|
242
|
+
engine = double("engine")
|
|
243
|
+
faux_key = double("faux_key")
|
|
244
|
+
|
|
245
|
+
public_key = OpenSSL::PKey::RSA.new("-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqLfP8948QEZMMkZNHLDP\nOHZVrPdVvecD6bp8dz96LalMQiWjgMkJf7mPHXoNMQ5rIpntiUOmhupu+sty30+C\ndbZZIbZohioTSYq9ZIC/LC9ME12F78GRMKhBGA+ZiouzWvXqOEdMnanfSgKrlSIS\nssF71dfmOEQ08fn9Vl5jAgWmGe+v615iHqBNGr64kYooTrZYLaPlTScO1UZ76vnB\nHfNQU+tsEZNXxtZXKQqkxHxLShCOj6qmYRNn/upTZoWWd04+zXjYGEC3eKvi9ctN\n9FY+KJ6QCCa8H0Kt3cU5qyw6pzdljhbG6NKhod7OMqlGjmHdsCAYAqe3xH+V/8oe\ndwIDAQAB\n-----END PUBLIC KEY-----\n")
|
|
246
|
+
|
|
247
|
+
conf.should_receive(:kind_of?).with(Hash).and_return(true)
|
|
248
|
+
conf.should_receive(:[]).with("ca_cert").and_return(
|
|
249
|
+
"cert" => "#{File.dirname(__FILE__)}/fixtures/test_ca.cer",
|
|
250
|
+
"engine" => engine,
|
|
251
|
+
"key_name" => "r509_key"
|
|
252
|
+
)
|
|
253
|
+
conf.should_receive(:[]).at_least(1).times.and_return(nil)
|
|
254
|
+
conf.should_receive(:has_key?).at_least(1).times.and_return(false)
|
|
255
|
+
|
|
256
|
+
engine.should_receive(:respond_to?).with(:load_private_key).and_return(true)
|
|
257
|
+
engine.should_receive(:kind_of?).with(OpenSSL::Engine).and_return(true)
|
|
258
|
+
faux_key.should_receive(:public_key).and_return(public_key)
|
|
259
|
+
engine.should_receive(:load_private_key).with("r509_key").and_return(faux_key)
|
|
260
|
+
|
|
261
|
+
config = R509::Config::CaConfig.load_from_hash(conf)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it "should fail if YAML for ca_cert contains engine and key" do
|
|
265
|
+
expect { R509::Config::CaConfig.from_yaml("engine_and_key", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_engine_key.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"}) }.to raise_error(R509::R509Error, "You can't specify both key and engine")
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
it "should fail if YAML for ca_cert contains engine but no key_name" do
|
|
269
|
+
expect { R509::Config::CaConfig.from_yaml("engine_no_key_name", File.read("#{File.dirname(__FILE__)}/fixtures/config_test_engine_no_key_name.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"}) }.to raise_error(R509::R509Error, 'You must supply a key_name with an engine')
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
it "should fail if YAML config is null" do
|
|
273
|
+
expect{ R509::Config::CaConfig.from_yaml("no_config_here", File.read("#{File.dirname(__FILE__)}/fixtures/config_test.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"}) }.to raise_error(ArgumentError)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it "should fail if YAML config isn't a hash" do
|
|
277
|
+
expect{ R509::Config::CaConfig.from_yaml("config_is_string", File.read("#{File.dirname(__FILE__)}/fixtures/config_test.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"}) }.to raise_error(ArgumentError)
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it "should fail if YAML config doesn't give a root CA directory that's a directory" do
|
|
281
|
+
expect{ R509::Config::CaConfig.from_yaml("test_ca", File.read("#{File.dirname(__FILE__)}/fixtures/config_test.yaml"), {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures/no_directory_here"}) }.to raise_error(R509::R509Error)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
it "should load YAML from filename" do
|
|
285
|
+
config = R509::Config::CaConfig.load_yaml("test_ca", "#{File.dirname(__FILE__)}/fixtures/config_test.yaml", {:ca_root_path => "#{File.dirname(__FILE__)}/fixtures"})
|
|
286
|
+
config.crl_validity_hours.should == 72
|
|
287
|
+
config.ocsp_validity_hours.should == 96
|
|
288
|
+
config.message_digest.should == "SHA1"
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it "can specify crl_number_file" do
|
|
292
|
+
config = R509::Config::CaConfig.new(
|
|
293
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
294
|
+
:crl_number_file => "crl_number_file.txt"
|
|
295
|
+
)
|
|
296
|
+
config.crl_number_file.should == 'crl_number_file.txt'
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
it "can specify crl_list_file" do
|
|
300
|
+
config = R509::Config::CaConfig.new(
|
|
301
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
302
|
+
:crl_list_file => "crl_list_file.txt"
|
|
303
|
+
)
|
|
304
|
+
config.crl_list_file.should == 'crl_list_file.txt'
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
describe R509::Config::SubjectItemPolicy do
|
|
310
|
+
it "raises an error if you supply a non-hash" do
|
|
311
|
+
expect { R509::Config::SubjectItemPolicy.new('string') }.to raise_error(ArgumentError, "Must supply a hash in form 'shortname'=>'required/optional'")
|
|
312
|
+
end
|
|
313
|
+
it "raises an error if a required element is missing" do
|
|
314
|
+
subject_item_policy = R509::Config::SubjectItemPolicy.new("CN" => "required", "O" => "required", "OU" => "optional", "L" => "required")
|
|
315
|
+
subject = R509::Subject.new [["CN","langui.sh"],["OU","Org Unit"],["O","Org"]]
|
|
316
|
+
expect { subject_item_policy.validate_subject(subject) }.to raise_error(R509::R509Error, /This profile requires you supply/)
|
|
317
|
+
end
|
|
318
|
+
it "raises an error if your hash values are anything other than required or optional" do
|
|
319
|
+
expect { R509::Config::SubjectItemPolicy.new("CN" => "somethirdoption") }.to raise_error(ArgumentError, "Unknown subject item policy value. Allowed values are required and optional")
|
|
320
|
+
end
|
|
321
|
+
it "validates a subject with the same fields as the policy" do
|
|
322
|
+
subject_item_policy = R509::Config::SubjectItemPolicy.new("CN" => "required", "O" => "required", "OU" => "optional")
|
|
323
|
+
subject = R509::Subject.new [["CN","langui.sh"],["OU","Org Unit"],["O","Org"]]
|
|
324
|
+
validated_subject = subject_item_policy.validate_subject(subject)
|
|
325
|
+
validated_subject.to_s.should == subject.to_s
|
|
326
|
+
end
|
|
327
|
+
it "does not match if you get case of subject_item_policy element wrong" do
|
|
328
|
+
subject_item_policy = R509::Config::SubjectItemPolicy.new("cn" => "required")
|
|
329
|
+
subject = R509::Subject.new [["CN","langui.sh"]]
|
|
330
|
+
expect { subject_item_policy.validate_subject(subject) }.to raise_error(R509::R509Error, 'This profile requires you supply cn')
|
|
331
|
+
end
|
|
332
|
+
it "removes subject items that are not in the policy" do
|
|
333
|
+
subject_item_policy = R509::Config::SubjectItemPolicy.new("CN" => "required")
|
|
334
|
+
subject = R509::Subject.new [["CN","langui.sh"],["OU","Org Unit"],["O","Org"]]
|
|
335
|
+
validated_subject = subject_item_policy.validate_subject(subject)
|
|
336
|
+
validated_subject.to_s.should == "/CN=langui.sh"
|
|
337
|
+
end
|
|
338
|
+
it "does not reorder subject items as it validates" do
|
|
339
|
+
subject_item_policy = R509::Config::SubjectItemPolicy.new("CN" => "required", "O" => "required", "OU" => "optional", "L" => "required")
|
|
340
|
+
subject = R509::Subject.new [["L","Chicago"],["CN","langui.sh"],["OU","Org Unit"],["O","Org"]]
|
|
341
|
+
validated_subject = subject_item_policy.validate_subject(subject)
|
|
342
|
+
validated_subject.to_s.should == subject.to_s
|
|
343
|
+
end
|
|
344
|
+
it "loads all the required and optional elements" do
|
|
345
|
+
subject_item_policy = R509::Config::SubjectItemPolicy.new("CN" => "required", "O" => "required", "OU" => "optional", "L" => "required", "emailAddress" => "optional")
|
|
346
|
+
subject_item_policy.optional.should include("OU","emailAddress")
|
|
347
|
+
subject_item_policy.required.should include("CN","O","L")
|
|
348
|
+
end
|
|
349
|
+
end
|
data/spec/crl_spec.rb
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'stringio'
|
|
3
|
+
|
|
4
|
+
describe R509::Crl::Parser do
|
|
5
|
+
before :each do
|
|
6
|
+
@crl_reason = TestFixtures::CRL_REASON
|
|
7
|
+
@crl = R509::Crl::Parser.new(@crl_reason)
|
|
8
|
+
@test_ca_cert = TestFixtures::TEST_CA_CERT
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "loads a crl with load_from_file" do
|
|
12
|
+
path = File.dirname(__FILE__) + '/fixtures/crl_with_reason.pem'
|
|
13
|
+
crl = R509::Crl::Parser.load_from_file path
|
|
14
|
+
crl.revoked[12345].should_not be_nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "returns issuer" do
|
|
18
|
+
@crl.issuer.to_s.should == "/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "returns last_update" do
|
|
22
|
+
@crl.last_update.should == Time.at(1327446093)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "returns next_update" do
|
|
26
|
+
@crl.next_update.should == Time.at(1328054493)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "returns signature_algorithm" do
|
|
30
|
+
@crl.signature_algorithm.should == "sha1WithRSAEncryption"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "verifies the CRL signature" do
|
|
34
|
+
cert = R509::Cert.new(:cert => @test_ca_cert)
|
|
35
|
+
@crl.verify(cert.public_key).should == true
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "checks if a serial is revoked?" do
|
|
39
|
+
@crl.revoked?(111111).should == false
|
|
40
|
+
@crl.revoked?(12345).should == true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "returns a hash of all revoked certs" do
|
|
44
|
+
@crl.revoked[12345][:time].should == Time.at(1327449693)
|
|
45
|
+
@crl.revoked[12345][:reason].should == "Key Compromise"
|
|
46
|
+
@crl.revoked[123456][:time].should == Time.at(1327449693)
|
|
47
|
+
@crl.revoked[123456][:reason].should == "Unspecified"
|
|
48
|
+
@crl.revoked[1234567][:time].should == Time.at(1327449693)
|
|
49
|
+
@crl.revoked[1234567][:reason].should == "Unspecified"
|
|
50
|
+
@crl.revoked[12345678].should == nil
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "returns revocation information for a serial" do
|
|
54
|
+
@crl.revoked_cert(11111).should == nil
|
|
55
|
+
revoked_info = @crl.revoked_cert(12345)
|
|
56
|
+
revoked_info[:time].should == Time.at(1327449693)
|
|
57
|
+
revoked_info[:reason].should == "Key Compromise"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe R509::Crl::Administrator do
|
|
62
|
+
before :each do
|
|
63
|
+
@cert = TestFixtures::CERT
|
|
64
|
+
@csr = TestFixtures::CSR
|
|
65
|
+
@csr3 = TestFixtures::CSR3
|
|
66
|
+
@test_ca_config = TestFixtures.test_ca_no_profile_config
|
|
67
|
+
end
|
|
68
|
+
it "generates CRL with no entries in revocation list" do
|
|
69
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
70
|
+
crl.generate_crl
|
|
71
|
+
crl.to_pem.should match(/BEGIN X509 CRL/)
|
|
72
|
+
end
|
|
73
|
+
it "raises exception when no R509::Config::CaConfig object is passed to the constructor" do
|
|
74
|
+
expect { R509::Crl::Administrator.new(['random']) }.to raise_error(R509::R509Error)
|
|
75
|
+
end
|
|
76
|
+
it "can write the crl_number_file" do
|
|
77
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
78
|
+
crl.crl_number_file.string.should == "1"
|
|
79
|
+
crl.crl_number_file.reopen("")
|
|
80
|
+
crl.save_crl_number
|
|
81
|
+
crl.crl_number_file.string.should == "1"
|
|
82
|
+
end
|
|
83
|
+
it "adds a cert to the revocation list" do
|
|
84
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
85
|
+
crl.revoked?(383834832).should == false
|
|
86
|
+
crl.revoke_cert(383834832)
|
|
87
|
+
crl.revoked?(383834832).should == true
|
|
88
|
+
parsed_crl = OpenSSL::X509::CRL.new(crl.to_der)
|
|
89
|
+
parsed_crl.revoked[0].serial.should == 383834832
|
|
90
|
+
end
|
|
91
|
+
it "can revoke (with reason)" do
|
|
92
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
93
|
+
crl.revoked?(12345).should == false
|
|
94
|
+
crl.revoke_cert(12345, 1)
|
|
95
|
+
crl.revoked?(12345).should == true
|
|
96
|
+
crl.revoked_cert(12345)[:reason].should == 1
|
|
97
|
+
|
|
98
|
+
parsed_crl = OpenSSL::X509::CRL.new(crl.to_pem)
|
|
99
|
+
parsed_crl.revoked[0].serial.should == 12345
|
|
100
|
+
parsed_crl.revoked[0].extensions[0].oid.should == "CRLReason"
|
|
101
|
+
parsed_crl.revoked[0].extensions[0].value.should == "Key Compromise"
|
|
102
|
+
end
|
|
103
|
+
it "cannot revoke the same serial twice" do
|
|
104
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
105
|
+
crl.revoked?(12345).should == false
|
|
106
|
+
crl.revoke_cert(12345, 1)
|
|
107
|
+
crl.revoked?(12345).should == true
|
|
108
|
+
crl.revoked_cert(12345)[:reason].should == 1
|
|
109
|
+
expect { crl.revoke_cert(12345, 1) }.to raise_error(R509::R509Error, "Cannot revoke a previously revoked certificate")
|
|
110
|
+
crl.revoked?(12345).should == true
|
|
111
|
+
end
|
|
112
|
+
it "adds a cert to the revocation list with an invalid reason code" do
|
|
113
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
114
|
+
crl.revoke_cert(383834832,15)
|
|
115
|
+
crl.generate_crl.should match(/BEGIN X509 CRL/)
|
|
116
|
+
crl.revoked?(383834832).should == true
|
|
117
|
+
crl.revoked_cert(383834832)[:reason].should == 0
|
|
118
|
+
end
|
|
119
|
+
it "removes a cert from the revocation list" do
|
|
120
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
121
|
+
crl.revoke_cert(383834832)
|
|
122
|
+
crl.revoked?(383834832).should == true
|
|
123
|
+
parsed_crl = OpenSSL::X509::CRL.new(crl.to_pem)
|
|
124
|
+
parsed_crl.revoked[0].serial.should == 383834832
|
|
125
|
+
crl.unrevoke_cert(383834832)
|
|
126
|
+
crl.revoked?(383834832).should == false
|
|
127
|
+
parsed_crl = OpenSSL::X509::CRL.new(crl.to_pem)
|
|
128
|
+
parsed_crl.revoked.empty?.should == true
|
|
129
|
+
end
|
|
130
|
+
it "loads an existing revocation list file" do
|
|
131
|
+
config = R509::Config::CaConfig.new(
|
|
132
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
133
|
+
:crl_list_file => TestFixtures::CRL_LIST_FILE
|
|
134
|
+
)
|
|
135
|
+
crl = R509::Crl::Administrator.new(config)
|
|
136
|
+
crl.revoked?(12345).should == true
|
|
137
|
+
crl.revoked_cert(12345)[:revoke_time].should == 1323983885
|
|
138
|
+
crl.revoked_cert(12345)[:reason].should == 0
|
|
139
|
+
|
|
140
|
+
end
|
|
141
|
+
it "when nil crl_list_file still call generate_crl" do
|
|
142
|
+
config = R509::Config::CaConfig.new(
|
|
143
|
+
:ca_cert => TestFixtures.test_ca_cert,
|
|
144
|
+
:crl_list_file => nil
|
|
145
|
+
)
|
|
146
|
+
crl = R509::Crl::Administrator.new(config)
|
|
147
|
+
crl.to_pem.should match(/BEGIN X509 CRL/)
|
|
148
|
+
end
|
|
149
|
+
it "sets validity via yaml" do
|
|
150
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
151
|
+
now = Time.at Time.now.to_i
|
|
152
|
+
crl.generate_crl
|
|
153
|
+
crl.next_update.should == (now+168*3600) #default 168 hours (7 days)
|
|
154
|
+
end
|
|
155
|
+
it "has a last_update time" do
|
|
156
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
157
|
+
now = Time.at Time.now.to_i
|
|
158
|
+
crl.generate_crl
|
|
159
|
+
crl.last_update.should == (now - @test_ca_config.crl_start_skew_seconds)
|
|
160
|
+
end
|
|
161
|
+
it "returns der" do
|
|
162
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
163
|
+
crl.generate_crl
|
|
164
|
+
parsed_crl = crl.to_crl
|
|
165
|
+
parsed_crl.issuer.to_s.should == '/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA'
|
|
166
|
+
parsed_crl.issuer_cn.should == 'Test CA'
|
|
167
|
+
end
|
|
168
|
+
it "returns pem" do
|
|
169
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
170
|
+
crl.generate_crl
|
|
171
|
+
parsed_crl = crl.to_crl
|
|
172
|
+
parsed_crl.issuer.to_s.should == '/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA'
|
|
173
|
+
parsed_crl.issuer_cn.should == 'Test CA'
|
|
174
|
+
end
|
|
175
|
+
it "writes to pem" do
|
|
176
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
177
|
+
crl.generate_crl
|
|
178
|
+
sio = StringIO.new
|
|
179
|
+
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
|
180
|
+
crl.write_pem(sio)
|
|
181
|
+
parsed_crl = R509::Crl::Parser.new(sio.string)
|
|
182
|
+
parsed_crl.issuer.to_s.should == '/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA'
|
|
183
|
+
parsed_crl.issuer_cn.should == 'Test CA'
|
|
184
|
+
end
|
|
185
|
+
it "writes to der" do
|
|
186
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
187
|
+
crl.generate_crl
|
|
188
|
+
sio = StringIO.new
|
|
189
|
+
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
|
190
|
+
crl.write_der(sio)
|
|
191
|
+
parsed_crl = R509::Crl::Parser.new(sio.string)
|
|
192
|
+
parsed_crl.issuer.to_s.should == '/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA'
|
|
193
|
+
parsed_crl.issuer_cn.should == 'Test CA'
|
|
194
|
+
end
|
|
195
|
+
it "writes crl list" do
|
|
196
|
+
crl = R509::Crl::Administrator.new(@test_ca_config)
|
|
197
|
+
crl.revoke_cert(12345)
|
|
198
|
+
crl.save_crl_list
|
|
199
|
+
crl.crl_list_file.string.should match(/[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+/)
|
|
200
|
+
end
|
|
201
|
+
it "doesn't write the crl_number_file when it is nil" do
|
|
202
|
+
config = R509::Config::CaConfig.new(
|
|
203
|
+
:ca_cert => TestFixtures.test_ca_cert
|
|
204
|
+
)
|
|
205
|
+
crl = R509::Crl::Administrator.new(config)
|
|
206
|
+
expect { crl.save_crl_number }.to_not raise_error(StandardError)
|
|
207
|
+
end
|
|
208
|
+
it "doesn't write the crl_list_file when it is nil" do
|
|
209
|
+
config = R509::Config::CaConfig.new(
|
|
210
|
+
:ca_cert => TestFixtures.test_ca_cert
|
|
211
|
+
)
|
|
212
|
+
crl = R509::Crl::Administrator.new(config)
|
|
213
|
+
expect { crl.save_crl_list }.to_not raise_error(StandardError)
|
|
214
|
+
end
|
|
215
|
+
end
|