r509 0.10.0 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.mdown +2 -2
- data/Rakefile +2 -3
- data/bin/r509 +77 -80
- data/bin/r509-parse +4 -4
- data/doc/R509.html +60 -60
- data/doc/R509/ASN1.html +158 -48
- data/doc/R509/ASN1/GeneralName.html +157 -154
- data/doc/R509/ASN1/GeneralNames.html +246 -237
- data/doc/R509/CRL.html +41 -39
- data/doc/R509/CRL/Administrator.html +105 -100
- data/doc/R509/CRL/FileReaderWriter.html +146 -98
- data/doc/R509/CRL/ReaderWriter.html +57 -54
- data/doc/R509/CRL/SQLiteReaderWriter.html +727 -0
- data/doc/R509/CRL/SignedList.html +83 -80
- data/doc/R509/CSR.html +184 -162
- data/doc/R509/Cert.html +271 -269
- data/doc/R509/Cert/Extensions.html +62 -63
- data/doc/R509/Cert/Extensions/AuthorityInfoAccess.html +138 -108
- data/doc/R509/Cert/Extensions/AuthorityKeyIdentifier.html +100 -84
- data/doc/R509/Cert/Extensions/BasicConstraints.html +89 -88
- data/doc/R509/Cert/Extensions/CRLDistributionPoints.html +87 -83
- data/doc/R509/Cert/Extensions/CertificatePolicies.html +78 -76
- data/doc/R509/Cert/Extensions/ExtendedKeyUsage.html +128 -125
- data/doc/R509/Cert/Extensions/GeneralNamesMixin.html +83 -78
- data/doc/R509/Cert/Extensions/InhibitAnyPolicy.html +69 -67
- data/doc/R509/Cert/Extensions/KeyUsage.html +138 -135
- data/doc/R509/Cert/Extensions/NameConstraints.html +82 -81
- data/doc/R509/Cert/Extensions/NoticeReference.html +59 -56
- data/doc/R509/Cert/Extensions/OCSPNoCheck.html +70 -69
- data/doc/R509/Cert/Extensions/PolicyConstraints.html +71 -69
- data/doc/R509/Cert/Extensions/PolicyInformation.html +63 -60
- data/doc/R509/Cert/Extensions/PolicyQualifiers.html +60 -57
- data/doc/R509/Cert/Extensions/SubjectAlternativeName.html +91 -87
- data/doc/R509/Cert/Extensions/SubjectKeyIdentifier.html +72 -71
- data/doc/R509/Cert/Extensions/UserNotice.html +60 -57
- data/doc/R509/Cert/Extensions/ValidationMixin.html +43 -40
- data/doc/R509/CertificateAuthority.html +39 -37
- data/doc/R509/CertificateAuthority/OptionsBuilder.html +58 -55
- data/doc/R509/CertificateAuthority/Signer.html +277 -60
- data/doc/R509/Config.html +40 -38
- data/doc/R509/Config/CAConfig.html +255 -188
- data/doc/R509/Config/CAConfigPool.html +64 -61
- data/doc/R509/Config/CertProfile.html +119 -116
- data/doc/R509/Config/SubjectItemPolicy.html +94 -93
- data/doc/R509/Engine.html +60 -56
- data/doc/R509/Helpers.html +99 -96
- data/doc/R509/MessageDigest.html +69 -68
- data/doc/R509/NameSanitizer.html +51 -48
- data/doc/R509/OCSP.html +39 -37
- data/doc/R509/OCSP/Request.html +39 -37
- data/doc/R509/OCSP/Request/Nonce.html +67 -67
- data/doc/R509/OCSP/Response.html +93 -90
- data/doc/R509/OIDMapper.html +48 -46
- data/doc/R509/PrivateKey.html +170 -169
- data/doc/R509/R509Error.html +45 -42
- data/doc/R509/SPKI.html +99 -89
- data/doc/R509/Subject.html +86 -83
- data/doc/R509/Validity.html +57 -57
- data/doc/R509/Validity/Checker.html +63 -93
- data/doc/R509/Validity/DefaultChecker.html +58 -55
- data/doc/R509/Validity/DefaultWriter.html +62 -59
- data/doc/R509/Validity/Status.html +77 -74
- data/doc/R509/Validity/Writer.html +75 -123
- data/doc/_index.html +37 -31
- data/doc/class_list.html +25 -27
- data/doc/css/full_list.css +32 -31
- data/doc/css/style.css +221 -78
- data/doc/file.CONTRIBUTING.html +29 -30
- data/doc/file.LICENSE.html +29 -30
- data/doc/file.README.html +31 -32
- data/doc/file.YAML.html +33 -34
- data/doc/file.r509.html +39 -48
- data/doc/file_list.html +39 -30
- data/doc/frames.html +10 -21
- data/doc/index.html +31 -32
- data/doc/js/app.js +100 -71
- data/doc/js/full_list.js +168 -130
- data/doc/method_list.html +1788 -1119
- data/doc/top-level-namespace.html +45 -49
- data/lib/r509.rb +21 -7
- data/lib/r509/asn1.rb +45 -32
- data/lib/r509/cert.rb +45 -51
- data/lib/r509/cert/extensions/authority_info_access.rb +49 -23
- data/lib/r509/cert/extensions/authority_key_identifier.rb +16 -11
- data/lib/r509/cert/extensions/base.rb +22 -23
- data/lib/r509/cert/extensions/basic_constraints.rb +11 -12
- data/lib/r509/cert/extensions/certificate_policies.rb +26 -26
- data/lib/r509/cert/extensions/crl_distribution_points.rb +5 -7
- data/lib/r509/cert/extensions/extended_key_usage.rb +5 -5
- data/lib/r509/cert/extensions/inhibit_any_policy.rb +4 -3
- data/lib/r509/cert/extensions/key_usage.rb +5 -5
- data/lib/r509/cert/extensions/name_constraints.rb +16 -16
- data/lib/r509/cert/extensions/ocsp_no_check.rb +3 -3
- data/lib/r509/cert/extensions/policy_constraints.rb +8 -8
- data/lib/r509/cert/extensions/subject_alternative_name.rb +5 -4
- data/lib/r509/cert/extensions/subject_key_identifier.rb +5 -5
- data/lib/r509/cert/extensions/validation_mixin.rb +11 -10
- data/lib/r509/certificate_authority/options_builder.rb +19 -21
- data/lib/r509/certificate_authority/signer.rb +26 -27
- data/lib/r509/config.rb +1 -0
- data/lib/r509/config/ca_config.rb +70 -75
- data/lib/r509/config/cert_profile.rb +9 -8
- data/lib/r509/config/subject_item_policy.rb +25 -28
- data/lib/r509/crl/administrator.rb +19 -20
- data/lib/r509/crl/reader_writer.rb +10 -8
- data/lib/r509/crl/signed_list.rb +4 -4
- data/lib/r509/crl/sqlite_reader_writer.rb +75 -0
- data/lib/r509/csr.rb +54 -60
- data/lib/r509/ec-hack.rb +3 -2
- data/lib/r509/engine.rb +5 -6
- data/lib/r509/exceptions.rb +1 -1
- data/lib/r509/helpers.rb +11 -14
- data/lib/r509/io_helpers.rb +7 -7
- data/lib/r509/message_digest.rb +5 -6
- data/lib/r509/ocsp.rb +11 -13
- data/lib/r509/oid_mapper.rb +2 -2
- data/lib/r509/private_key.rb +28 -32
- data/lib/r509/spki.rb +17 -20
- data/lib/r509/subject.rb +26 -27
- data/lib/r509/trollop.rb +1 -0
- data/lib/r509/validity.rb +30 -21
- data/lib/r509/version.rb +4 -2
- data/r509.yaml +9 -17
- data/spec/asn1_spec.rb +145 -146
- data/spec/cert/extensions/authority_info_access_spec.rb +41 -41
- data/spec/cert/extensions/authority_key_identifier_spec.rb +29 -23
- data/spec/cert/extensions/base_spec.rb +38 -34
- data/spec/cert/extensions/basic_constraints_spec.rb +21 -21
- data/spec/cert/extensions/certificate_policies_spec.rb +99 -87
- data/spec/cert/extensions/crl_distribution_points_spec.rb +24 -25
- data/spec/cert/extensions/extended_key_usage_spec.rb +40 -36
- data/spec/cert/extensions/inhibit_any_policy_spec.rb +12 -12
- data/spec/cert/extensions/key_usage_spec.rb +44 -39
- data/spec/cert/extensions/name_constraints_spec.rb +83 -83
- data/spec/cert/extensions/ocsp_no_check_spec.rb +10 -10
- data/spec/cert/extensions/policy_constraints_spec.rb +19 -19
- data/spec/cert/extensions/subject_alternative_name_spec.rb +46 -47
- data/spec/cert/extensions/subject_key_identifier_spec.rb +10 -10
- data/spec/cert_spec.rb +105 -101
- data/spec/certificate_authority/options_builder_spec.rb +90 -90
- data/spec/certificate_authority/signer_spec.rb +41 -41
- data/spec/config/ca_config_spec.rb +169 -119
- data/spec/config/cert_profile_spec.rb +33 -33
- data/spec/config/subject_item_policy_spec.rb +22 -22
- data/spec/crl/administrator_spec.rb +65 -65
- data/spec/crl/reader_writer_spec.rb +20 -19
- data/spec/crl/signed_list_spec.rb +26 -26
- data/spec/crl/sqlite_reader_writer_spec.rb +42 -0
- data/spec/csr_spec.rb +149 -145
- data/spec/engine_spec.rb +14 -14
- data/spec/fixtures.rb +56 -39
- data/spec/fixtures/crl_list.sql +13 -0
- data/spec/fixtures/csr1.der +0 -0
- data/spec/fixtures/csr1.pem +6 -6
- data/spec/message_digest_spec.rb +43 -43
- data/spec/ocsp_spec.rb +25 -25
- data/spec/oid_mapper_spec.rb +18 -19
- data/spec/private_key_spec.rb +79 -81
- data/spec/r509_spec.rb +16 -16
- data/spec/spec_helper.rb +3 -3
- data/spec/spki_spec.rb +94 -94
- data/spec/subject_spec.rb +107 -107
- data/spec/validity_spec.rb +25 -25
- metadata +113 -111
- metadata.gz.sig +0 -0
data/spec/engine_spec.rb
CHANGED
@@ -19,33 +19,33 @@ describe R509::Engine do
|
|
19
19
|
|
20
20
|
it "raises an error if you don't supply an :so_path and :id" do
|
21
21
|
expect { R509::Engine.instance.load("not even a hash") }.to raise_error(ArgumentError, "You must supply a hash with both :so_path and :id")
|
22
|
-
expect { R509::Engine.instance.load(
|
22
|
+
expect { R509::Engine.instance.load(:so_path => "path") }.to raise_error(ArgumentError, "You must supply a hash with both :so_path and :id")
|
23
23
|
end
|
24
24
|
|
25
25
|
it "load returns a new engine" do
|
26
|
-
OpenSSL::Engine.
|
26
|
+
expect(OpenSSL::Engine).to receive(:load)
|
27
27
|
engine_double = double('engine')
|
28
|
-
OpenSSL::Engine.
|
29
|
-
engine_double.
|
30
|
-
engine_double.
|
31
|
-
engine_double.
|
28
|
+
expect(OpenSSL::Engine).to receive(:by_id).and_yield(engine_double).and_return(engine_double)
|
29
|
+
expect(engine_double).to receive(:ctrl_cmd).with("SO_PATH", "/some/path")
|
30
|
+
expect(engine_double).to receive(:ctrl_cmd).with("ID", "mocked")
|
31
|
+
expect(engine_double).to receive(:ctrl_cmd).with("LOAD")
|
32
32
|
engine = R509::Engine.instance.load(:so_path => "/some/path", :id => "mocked")
|
33
|
-
engine.
|
33
|
+
expect(engine).to eq(engine_double)
|
34
34
|
end
|
35
35
|
|
36
36
|
it "load returns pre-existing engine" do
|
37
|
-
OpenSSL::Engine.
|
38
|
-
OpenSSL::Engine.
|
37
|
+
expect(OpenSSL::Engine).to receive(:load)
|
38
|
+
expect(OpenSSL::Engine).to receive(:by_id).and_return("mocked_engine")
|
39
39
|
R509::Engine.instance.load(:so_path => "/some/path", :id => "mocked")
|
40
40
|
engine = R509::Engine.instance.load(:so_path => "/some/path", :id => "mocked")
|
41
|
-
engine.
|
41
|
+
expect(engine).to eq('mocked_engine')
|
42
42
|
end
|
43
43
|
|
44
44
|
it "returns an engine with []" do
|
45
|
-
OpenSSL::Engine.
|
46
|
-
OpenSSL::Engine.
|
45
|
+
expect(OpenSSL::Engine).to receive(:load)
|
46
|
+
expect(OpenSSL::Engine).to receive(:by_id).and_return("mocked_engine")
|
47
47
|
R509::Engine.instance.load(:so_path => "/some/path", :id => "mocked")
|
48
|
-
R509::Engine.instance["mocked"].
|
49
|
-
R509::Engine.instance["other"].
|
48
|
+
expect(R509::Engine.instance["mocked"]).to eq("mocked_engine")
|
49
|
+
expect(R509::Engine.instance["other"]).to be_nil
|
50
50
|
end
|
51
51
|
end
|
data/spec/fixtures.rb
CHANGED
@@ -2,6 +2,7 @@ require 'spec_helper'
|
|
2
2
|
require 'pathname'
|
3
3
|
require 'r509/io_helpers'
|
4
4
|
|
5
|
+
# Contains constants and other values for testing purposes
|
5
6
|
module TestFixtures
|
6
7
|
extend R509::IOHelpers
|
7
8
|
|
@@ -11,14 +12,14 @@ module TestFixtures
|
|
11
12
|
read_data((FIXTURES_PATH + filename).to_s)
|
12
13
|
end
|
13
14
|
|
14
|
-
#Trustwave cert for langui.sh
|
15
|
+
# Trustwave cert for langui.sh
|
15
16
|
CERT = read_fixture('cert1.pem')
|
16
17
|
|
17
18
|
CERT_INHIBIT = read_fixture('cert_inhibit.pem')
|
18
19
|
CERT_POLICY_CONSTRAINTS = read_fixture('cert_policy_constraints.pem')
|
19
20
|
CERT_NAME_CONSTRAINTS = read_fixture('cert_name_constraints.pem')
|
20
21
|
|
21
|
-
#Trustwave root cert
|
22
|
+
# Trustwave root cert
|
22
23
|
STCA_CERT = read_fixture('stca.pem')
|
23
24
|
|
24
25
|
CERT_PUBLIC_KEY_MODULUS = read_fixture('cert1_public_key_modulus.txt')
|
@@ -41,11 +42,10 @@ module TestFixtures
|
|
41
42
|
# this CSR has unknown OIDs, which we should successfully parse out into Subject
|
42
43
|
CSR_UNKNOWN_OID = read_fixture('unknown_oid.csr')
|
43
44
|
|
44
|
-
|
45
|
-
#san cert from self-signed CA for langui.sh
|
45
|
+
# san cert from self-signed CA for langui.sh
|
46
46
|
CERT_SAN = read_fixture('cert_san.pem')
|
47
47
|
|
48
|
-
#Another san cert for langui.sh, but differentiating between the CN and
|
48
|
+
# Another san cert for langui.sh, but differentiating between the CN and
|
49
49
|
# SANs.
|
50
50
|
CERT_SAN2 = read_fixture('cert_san2.pem')
|
51
51
|
|
@@ -136,10 +136,10 @@ module TestFixtures
|
|
136
136
|
TEST_CA_SUBROOT_CERT = read_fixture('test_ca_subroot.cer')
|
137
137
|
TEST_CA_SUBROOT_KEY = read_fixture('test_ca_subroot.key')
|
138
138
|
|
139
|
-
#this chain contains 2 certs. root and OCSP delegate
|
140
|
-
#in a prod environment you'd really only need the delegate
|
141
|
-
#since the root would be present in the root store of the
|
142
|
-
#client, but I wanted to test > 1
|
139
|
+
# this chain contains 2 certs. root and OCSP delegate
|
140
|
+
# in a prod environment you'd really only need the delegate
|
141
|
+
# since the root would be present in the root store of the
|
142
|
+
# client, but I wanted to test > 1
|
143
143
|
TEST_CA_OCSP_CHAIN = read_fixture('test_ca_ocsp_chain.txt')
|
144
144
|
|
145
145
|
TEST_CA_OCSP_RESPONSE = read_fixture('test_ca_ocsp_response.der')
|
@@ -155,13 +155,14 @@ module TestFixtures
|
|
155
155
|
STCA_OCSP_REQUEST = read_fixture('stca_ocsp_request.der')
|
156
156
|
STCA_OCSP_RESPONSE = read_fixture('stca_ocsp_response.der')
|
157
157
|
|
158
|
-
CRL_LIST_FILE = (FIXTURES_PATH+'crl_list_file.txt').to_s
|
158
|
+
CRL_LIST_FILE = (FIXTURES_PATH + 'crl_list_file.txt').to_s
|
159
159
|
|
160
160
|
CRL_REASON = read_fixture("crl_with_reason.pem")
|
161
161
|
|
162
162
|
HMACSHA512_SIG = read_fixture("hmacsha512.sig")
|
163
163
|
HMACSHA1_SIG = read_fixture("hmacsha1.sig")
|
164
164
|
|
165
|
+
CRL_LIST_SQLITE = read_fixture("crl_list.sql")
|
165
166
|
def self.test_ca_cert
|
166
167
|
R509::Cert.new(:cert => TEST_CA_CERT, :key => TEST_CA_KEY)
|
167
168
|
end
|
@@ -184,53 +185,69 @@ module TestFixtures
|
|
184
185
|
|
185
186
|
def self.test_ca_server_profile
|
186
187
|
R509::Config::CertProfile.new(
|
187
|
-
:basic_constraints => R509::Cert::Extensions::BasicConstraints.new(
|
188
|
-
:key_usage => R509::Cert::Extensions::KeyUsage.new(:value => ["digitalSignature","keyEncipherment"]),
|
188
|
+
:basic_constraints => R509::Cert::Extensions::BasicConstraints.new(:ca => false),
|
189
|
+
:key_usage => R509::Cert::Extensions::KeyUsage.new(:value => ["digitalSignature", "keyEncipherment"]),
|
189
190
|
:extended_key_usage => R509::Cert::Extensions::ExtendedKeyUsage.new(:value => ["serverAuth"]),
|
190
|
-
:certificate_policies => R509::Cert::Extensions::CertificatePolicies.new(
|
191
|
+
:certificate_policies => R509::Cert::Extensions::CertificatePolicies.new(
|
192
|
+
:value => [
|
191
193
|
{ :policy_identifier => "2.16.840.1.12345.1.2.3.4.1",
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
194
|
+
:cps_uris => ["http://example.com/cps", "http://other.com/cps"],
|
195
|
+
:user_notices => [
|
196
|
+
{
|
197
|
+
:explicit_text => "thing",
|
198
|
+
:organization => "my org",
|
199
|
+
:notice_numbers => [1, 2, 3, 4]
|
200
|
+
}
|
201
|
+
]
|
202
|
+
}
|
203
|
+
]
|
204
|
+
)
|
196
205
|
)
|
197
|
-
|
198
206
|
end
|
199
207
|
|
200
208
|
def self.test_ca_server_profile_with_subject_item_policy
|
201
209
|
subject_item_policy = R509::Config::SubjectItemPolicy.new(
|
202
|
-
"CN" => { :policy => "required"},
|
203
|
-
"O" => { :policy => "optional"},
|
204
|
-
"ST" => { :policy => "required"},
|
205
|
-
"C" => { :policy => "required"},
|
206
|
-
"OU" => { :policy => "optional"}
|
210
|
+
"CN" => { :policy => "required" },
|
211
|
+
"O" => { :policy => "optional" },
|
212
|
+
"ST" => { :policy => "required" },
|
213
|
+
"C" => { :policy => "required" },
|
214
|
+
"OU" => { :policy => "optional" }
|
207
215
|
)
|
208
216
|
R509::Config::CertProfile.new(
|
209
|
-
:basic_constraints => R509::Cert::Extensions::BasicConstraints.new(
|
210
|
-
:key_usage => R509::Cert::Extensions::KeyUsage.new(:value => ["digitalSignature","keyEncipherment"]),
|
217
|
+
:basic_constraints => R509::Cert::Extensions::BasicConstraints.new(:ca => false),
|
218
|
+
:key_usage => R509::Cert::Extensions::KeyUsage.new(:value => ["digitalSignature", "keyEncipherment"]),
|
211
219
|
:extended_key_usage => R509::Cert::Extensions::ExtendedKeyUsage.new(:value => ["serverAuth"]),
|
212
|
-
:certificate_policies => R509::Cert::Extensions::CertificatePolicies.new(
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
220
|
+
:certificate_policies => R509::Cert::Extensions::CertificatePolicies.new(
|
221
|
+
:value => [
|
222
|
+
{
|
223
|
+
:policy_identifier => "2.16.840.1.12345.1.2.3.4.1",
|
224
|
+
:cps_uris => ["http://example.com/cps", "http://other.com/cps"],
|
225
|
+
:user_notices => [
|
226
|
+
{
|
227
|
+
:explicit_text => "thing",
|
228
|
+
:organization => "my org",
|
229
|
+
:notice_numbers => [1, 2, 3, 4]
|
230
|
+
}
|
231
|
+
]
|
232
|
+
}
|
233
|
+
]
|
234
|
+
),
|
218
235
|
:subject_item_policy => subject_item_policy
|
219
236
|
)
|
220
237
|
end
|
221
238
|
|
222
239
|
def self.test_ca_subroot_profile
|
223
240
|
R509::Config::CertProfile.new(
|
224
|
-
:basic_constraints => {:ca => true, :path_length => 0 },
|
225
|
-
:key_usage => {:value => ["keyCertSign","cRLSign"]},
|
241
|
+
:basic_constraints => { :ca => true, :path_length => 0 },
|
242
|
+
:key_usage => { :value => ["keyCertSign", "cRLSign"] },
|
226
243
|
:certificate_policies => nil)
|
227
244
|
end
|
228
245
|
|
229
246
|
def self.test_ca_ocspsigner_profile
|
230
247
|
R509::Config::CertProfile.new(
|
231
248
|
:basic_constraints => { :ca => false },
|
232
|
-
:key_usage => {:value => ["digitalSignature"]},
|
233
|
-
:extended_key_usage => {:value => ["OCSPSigning"]},
|
249
|
+
:key_usage => { :value => ["digitalSignature"] },
|
250
|
+
:extended_key_usage => { :value => ["OCSPSigning"] },
|
234
251
|
:certificate_policies => nil)
|
235
252
|
end
|
236
253
|
|
@@ -242,7 +259,7 @@ module TestFixtures
|
|
242
259
|
crl_number_sio.set_encoding("BINARY") if crl_number_sio.respond_to?(:set_encoding)
|
243
260
|
|
244
261
|
opts = {
|
245
|
-
:ca_cert => test_ca_cert
|
262
|
+
:ca_cert => test_ca_cert,
|
246
263
|
:ocsp_start_skew_seconds => 3600,
|
247
264
|
:ocsp_validity_hours => 48,
|
248
265
|
:crl_list_file => crl_list_sio,
|
@@ -266,7 +283,7 @@ module TestFixtures
|
|
266
283
|
crl_number_sio.set_encoding("BINARY") if crl_number_sio.respond_to?(:set_encoding)
|
267
284
|
|
268
285
|
opts = {
|
269
|
-
:ca_cert => test_ca_cert
|
286
|
+
:ca_cert => test_ca_cert,
|
270
287
|
:ocsp_start_skew_seconds => 3600,
|
271
288
|
:ocsp_validity_hours => 48,
|
272
289
|
:crl_list_file => crl_list_sio,
|
@@ -282,7 +299,7 @@ module TestFixtures
|
|
282
299
|
crl_number_sio.set_encoding("BINARY") if crl_number_sio.respond_to?(:set_encoding)
|
283
300
|
|
284
301
|
opts = {
|
285
|
-
:ca_cert => test_ca_ec_cert
|
302
|
+
:ca_cert => test_ca_ec_cert,
|
286
303
|
:ocsp_start_skew_seconds => 3600,
|
287
304
|
:ocsp_validity_hours => 48,
|
288
305
|
:crl_list_file => crl_list_sio,
|
@@ -298,7 +315,7 @@ module TestFixtures
|
|
298
315
|
crl_number_sio.set_encoding("BINARY") if crl_number_sio.respond_to?(:set_encoding)
|
299
316
|
|
300
317
|
opts = {
|
301
|
-
:ca_cert => test_ca_dsa_cert
|
318
|
+
:ca_cert => test_ca_dsa_cert,
|
302
319
|
:ocsp_start_skew_seconds => 3600,
|
303
320
|
:ocsp_validity_hours => 48,
|
304
321
|
:crl_list_file => crl_list_sio,
|
@@ -0,0 +1,13 @@
|
|
1
|
+
-- CREATE SCHEMA
|
2
|
+
CREATE TABLE revoked_serials(
|
3
|
+
serial TEXT NOT NULL PRIMARY KEY,
|
4
|
+
reason INTEGER,
|
5
|
+
revoked_at INTEGER NOT NULL
|
6
|
+
);
|
7
|
+
CREATE TABLE crl_number(
|
8
|
+
number INTEGER NOT NULL DEFAULT 0
|
9
|
+
);
|
10
|
+
INSERT INTO crl_number DEFAULT VALUES;
|
11
|
+
-- LOAD DATA
|
12
|
+
INSERT INTO revoked_serials (serial, reason, revoked_at) VALUES ('12345',0,1323983885);
|
13
|
+
INSERT INTO revoked_serials (serial, reason, revoked_at) VALUES ('12346',null,1323983885);
|
data/spec/fixtures/csr1.der
CHANGED
Binary file
|
data/spec/fixtures/csr1.pem
CHANGED
@@ -8,10 +8,10 @@ C9eMVvImjd3jGROT7FoqNz/TgQR5c09O8z0uwlaZsQqsD2SaiFOZj/jS+bxkxAjk
|
|
8
8
|
UEM60RjBkX82LdLmvRBGRhGVGMgs9DJESGIF9wt3MmDQPoLzsB1uuDaaOhWBCGse
|
9
9
|
IrxVunIcZHANAgMBAAGgSzBJBgkqhkiG9w0BCQ4xPDA6MDgGA1UdEQQxMC+CCnRl
|
10
10
|
c3QubG9jYWyCFWFkZGl0aW9uYWxkb21haW5zLmNvbYIKc2FuaWFtLmNvbTANBgkq
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
hkiG9w0BAQsFAAOCAQEAIbw5ZthNbw7zldPXzDKzj6YmxKRXt/qg2bzGUW25kX24
|
12
|
+
Lwsc9Ph42QU9vWP8CRZKMP4GxyH/BIRFRq7GD3mCihKet2I02SE9qIeMM3U1dFFX
|
13
|
+
08XS1WT9eQk4CUhyqBymk2q5gI4Y//dLpnvhcBNB1GBo6Q1/7PSEXgazp0uqJbo6
|
14
|
+
1fu4HbZEfQXqneG4KbKNYpGm2MceLhaYYZgU3FdMlKXJcRSKjif/86EabDAwh195
|
15
|
+
S4mR6hFXg5g/FtO/hzam3oxOBoJVU6W8X/VGxZ8yqtY9E0t7gwTqAw0RlBjwSoTu
|
16
|
+
zk5+RJ6mVDahjhLZsZY9Q+YAppNP8aP1UQe2U0+otQ==
|
17
17
|
-----END CERTIFICATE REQUEST-----
|
data/spec/message_digest_spec.rb
CHANGED
@@ -5,111 +5,111 @@ require 'openssl'
|
|
5
5
|
describe R509::MessageDigest do
|
6
6
|
it "translates sha1 name -> digest" do
|
7
7
|
md = R509::MessageDigest.new("sha1")
|
8
|
-
md.name.
|
9
|
-
md.digest.
|
8
|
+
expect(md.name).to eq("sha1")
|
9
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA1)).to eq(true)
|
10
10
|
end
|
11
11
|
it "translates SHA1 name -> digest" do
|
12
12
|
md = R509::MessageDigest.new("SHA1")
|
13
|
-
md.name.
|
14
|
-
md.digest.
|
13
|
+
expect(md.name).to eq("sha1")
|
14
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA1)).to eq(true)
|
15
15
|
end
|
16
16
|
it "translates sha224 name -> digest" do
|
17
17
|
md = R509::MessageDigest.new("sha224")
|
18
|
-
md.name.
|
19
|
-
md.digest.
|
18
|
+
expect(md.name).to eq("sha224")
|
19
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA224)).to eq(true)
|
20
20
|
end
|
21
21
|
it "translates sha256 name -> digest" do
|
22
22
|
md = R509::MessageDigest.new("sha256")
|
23
|
-
md.name.
|
24
|
-
md.digest.
|
23
|
+
expect(md.name).to eq("sha256")
|
24
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA256)).to eq(true)
|
25
25
|
end
|
26
26
|
it "translates SHA256 name -> digest" do
|
27
27
|
md = R509::MessageDigest.new("SHA256")
|
28
|
-
md.name.
|
29
|
-
md.digest.
|
28
|
+
expect(md.name).to eq("sha256")
|
29
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA256)).to eq(true)
|
30
30
|
end
|
31
31
|
it "translates SHA384 name -> digest" do
|
32
32
|
md = R509::MessageDigest.new("SHA384")
|
33
|
-
md.name.
|
34
|
-
md.digest.
|
33
|
+
expect(md.name).to eq("sha384")
|
34
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA384)).to eq(true)
|
35
35
|
end
|
36
36
|
it "translates sha512 name -> digest" do
|
37
37
|
md = R509::MessageDigest.new("sha512")
|
38
|
-
md.name.
|
39
|
-
md.digest.
|
38
|
+
expect(md.name).to eq("sha512")
|
39
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA512)).to eq(true)
|
40
40
|
end
|
41
41
|
it "translates SHA512 name -> digest" do
|
42
42
|
md = R509::MessageDigest.new("SHA512")
|
43
|
-
md.name.
|
44
|
-
md.digest.
|
43
|
+
expect(md.name).to eq("sha512")
|
44
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA512)).to eq(true)
|
45
45
|
end
|
46
46
|
it "translates md5 name -> digest" do
|
47
47
|
md = R509::MessageDigest.new("md5")
|
48
|
-
md.name.
|
49
|
-
md.digest.
|
48
|
+
expect(md.name).to eq("md5")
|
49
|
+
expect(md.digest.is_a?(OpenSSL::Digest::MD5)).to eq(true)
|
50
50
|
end
|
51
51
|
it "translates MD5 name -> digest" do
|
52
52
|
md = R509::MessageDigest.new("MD5")
|
53
|
-
md.name.
|
54
|
-
md.digest.
|
53
|
+
expect(md.name).to eq("md5")
|
54
|
+
expect(md.digest.is_a?(OpenSSL::Digest::MD5)).to eq(true)
|
55
55
|
end
|
56
56
|
it "translates dss1 name -> digest" do
|
57
57
|
md = R509::MessageDigest.new("dss1")
|
58
|
-
md.name.
|
59
|
-
md.digest.
|
58
|
+
expect(md.name).to eq("dss1")
|
59
|
+
expect(md.digest.is_a?(OpenSSL::Digest::DSS1)).to eq(true)
|
60
60
|
end
|
61
61
|
it "translates DSS1 name -> digest" do
|
62
62
|
md = R509::MessageDigest.new("DSS1")
|
63
|
-
md.name.
|
64
|
-
md.digest.
|
63
|
+
expect(md.name).to eq("dss1")
|
64
|
+
expect(md.digest.is_a?(OpenSSL::Digest::DSS1)).to eq(true)
|
65
65
|
end
|
66
66
|
it "translates unknown name -> digest" do
|
67
67
|
md = R509::MessageDigest.new("unknown")
|
68
|
-
md.name.
|
69
|
-
md.digest.
|
68
|
+
expect(md.name).to eq("sha256")
|
69
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA256)).to eq(true)
|
70
70
|
end
|
71
71
|
it "translates sha1 digest -> name" do
|
72
72
|
md = R509::MessageDigest.new(OpenSSL::Digest::SHA1.new)
|
73
|
-
md.name.
|
74
|
-
md.digest.
|
73
|
+
expect(md.name).to eq("sha1")
|
74
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA1)).to eq(true)
|
75
75
|
end
|
76
76
|
it "translates sha224 digest -> name" do
|
77
77
|
md = R509::MessageDigest.new(OpenSSL::Digest::SHA224.new)
|
78
|
-
md.name.
|
79
|
-
md.digest.
|
78
|
+
expect(md.name).to eq("sha224")
|
79
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA224)).to eq(true)
|
80
80
|
end
|
81
81
|
it "translates sha256 digest -> name" do
|
82
82
|
md = R509::MessageDigest.new(OpenSSL::Digest::SHA256.new)
|
83
|
-
md.name.
|
84
|
-
md.digest.
|
83
|
+
expect(md.name).to eq("sha256")
|
84
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA256)).to eq(true)
|
85
85
|
end
|
86
86
|
it "translates sha384 digest -> name" do
|
87
87
|
md = R509::MessageDigest.new(OpenSSL::Digest::SHA384.new)
|
88
|
-
md.name.
|
89
|
-
md.digest.
|
88
|
+
expect(md.name).to eq("sha384")
|
89
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA384)).to eq(true)
|
90
90
|
end
|
91
91
|
it "translates sha512 digest -> name" do
|
92
92
|
md = R509::MessageDigest.new(OpenSSL::Digest::SHA512.new)
|
93
|
-
md.name.
|
94
|
-
md.digest.
|
93
|
+
expect(md.name).to eq("sha512")
|
94
|
+
expect(md.digest.is_a?(OpenSSL::Digest::SHA512)).to eq(true)
|
95
95
|
end
|
96
96
|
it "translates md5 digest -> name" do
|
97
97
|
md = R509::MessageDigest.new(OpenSSL::Digest::MD5.new)
|
98
|
-
md.name.
|
99
|
-
md.digest.
|
98
|
+
expect(md.name).to eq("md5")
|
99
|
+
expect(md.digest.is_a?(OpenSSL::Digest::MD5)).to eq(true)
|
100
100
|
end
|
101
101
|
it "translates dss1 digest -> name" do
|
102
102
|
md = R509::MessageDigest.new(OpenSSL::Digest::DSS1.new)
|
103
|
-
md.name.
|
104
|
-
md.digest.
|
103
|
+
expect(md.name).to eq("dss1")
|
104
|
+
expect(md.digest.is_a?(OpenSSL::Digest::DSS1)).to eq(true)
|
105
105
|
end
|
106
106
|
it "creates a default digest with no params or nil" do
|
107
107
|
md = R509::MessageDigest.new
|
108
|
-
md.name.
|
108
|
+
expect(md.name).to eq(R509::MessageDigest::DEFAULT_MD.downcase)
|
109
109
|
md = R509::MessageDigest.new(nil)
|
110
|
-
md.name.
|
110
|
+
expect(md.name).to eq(R509::MessageDigest::DEFAULT_MD.downcase)
|
111
111
|
end
|
112
112
|
it "exception on unknown digest -> name" do
|
113
|
-
expect{ R509::MessageDigest.new(12345) }.to raise_error(ArgumentError)
|
113
|
+
expect { R509::MessageDigest.new(12345) }.to raise_error(ArgumentError)
|
114
114
|
end
|
115
115
|
end
|
data/spec/ocsp_spec.rb
CHANGED
@@ -19,37 +19,37 @@ describe R509::OCSP::Response do
|
|
19
19
|
end
|
20
20
|
it "parses a response der and returns the right object on #parse" do
|
21
21
|
ocsp_response = R509::OCSP::Response.parse(@ocsp_response_der)
|
22
|
-
ocsp_response.
|
23
|
-
ocsp_response.status.
|
22
|
+
expect(ocsp_response.is_a?(R509::OCSP::Response)).to eq(true)
|
23
|
+
expect(ocsp_response.status).to eq(OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL)
|
24
24
|
end
|
25
25
|
it "returns data on to_der" do
|
26
26
|
ocsp_response = R509::OCSP::Response.parse(@ocsp_response_der)
|
27
|
-
ocsp_response.to_der.
|
27
|
+
expect(ocsp_response.to_der).not_to be_nil
|
28
28
|
end
|
29
29
|
it "returns a BasicResponse object on #basic" do
|
30
30
|
ocsp_response = R509::OCSP::Response.parse(@ocsp_response_der)
|
31
|
-
ocsp_response.basic.
|
31
|
+
expect(ocsp_response.basic.is_a?(OpenSSL::OCSP::BasicResponse)).to eq(true)
|
32
32
|
end
|
33
33
|
it "returns true if response verifies (in validity period, chain builds to trusted root that's provided)" do
|
34
34
|
ocsp_response = R509::OCSP::Response.parse(@test_ca_ocsp_response)
|
35
|
-
ocsp_response.verify(TestFixtures.test_ca_config.ca_cert.cert).
|
35
|
+
expect(ocsp_response.verify(TestFixtures.test_ca_config.ca_cert.cert)).to eq(true)
|
36
36
|
end
|
37
37
|
it "verify supports an single certificate and uses it to validate" do
|
38
38
|
ocsp_response = R509::OCSP::Response.parse(@test_ca_ocsp_response)
|
39
|
-
ocsp_response.verify(TestFixtures.test_ca_config.ca_cert.cert).
|
39
|
+
expect(ocsp_response.verify(TestFixtures.test_ca_config.ca_cert.cert)).to eq(true)
|
40
40
|
end
|
41
41
|
it "verify supports an array of certificates and uses all of them to validate a chain" do
|
42
42
|
ocsp_response = R509::OCSP::Response.parse(@test_ca_subroot_ocsp_response)
|
43
|
-
ocsp_response.verify([TestFixtures.test_ca_config.ca_cert.cert,TestFixtures.test_ca_subroot_cert.cert]).
|
43
|
+
expect(ocsp_response.verify([TestFixtures.test_ca_config.ca_cert.cert, TestFixtures.test_ca_subroot_cert.cert])).to eq(true)
|
44
44
|
end
|
45
45
|
it "verify returns false if you don't give it enough certs to build a chain to a trusted root" do
|
46
46
|
ocsp_response = R509::OCSP::Response.parse(@test_ca_subroot_ocsp_response)
|
47
|
-
ocsp_response.verify([TestFixtures.test_ca_config.ca_cert.cert]).
|
47
|
+
expect(ocsp_response.verify([TestFixtures.test_ca_config.ca_cert.cert])).to eq(false)
|
48
48
|
end
|
49
49
|
it "returns false if response does not verify" do
|
50
|
-
#expired response
|
50
|
+
# expired response
|
51
51
|
ocsp_response = R509::OCSP::Response.parse(@ocsp_response_der)
|
52
|
-
ocsp_response.verify(OpenSSL::X509::Certificate.new(@stca_cert)).
|
52
|
+
expect(ocsp_response.verify(OpenSSL::X509::Certificate.new(@stca_cert))).to eq(false)
|
53
53
|
end
|
54
54
|
it "nonce is present and equal" do
|
55
55
|
ocsp_request = OpenSSL::OCSP::Request.new
|
@@ -57,20 +57,20 @@ describe R509::OCSP::Response do
|
|
57
57
|
basic_response = OpenSSL::OCSP::BasicResponse.new
|
58
58
|
basic_response.copy_nonce(ocsp_request)
|
59
59
|
response_double = double("ocsp_response")
|
60
|
-
response_double.
|
61
|
-
response_double.
|
60
|
+
expect(response_double).to receive(:is_a?).and_return('OpenSSL::OCSP::Response')
|
61
|
+
expect(response_double).to receive(:basic).and_return(basic_response)
|
62
62
|
ocsp_response = R509::OCSP::Response.new(response_double)
|
63
|
-
ocsp_response.check_nonce(ocsp_request).
|
63
|
+
expect(ocsp_response.check_nonce(ocsp_request)).to eq(R509::OCSP::Request::Nonce::PRESENT_AND_EQUAL)
|
64
64
|
end
|
65
65
|
it "no nonce" do
|
66
66
|
ocsp_request = OpenSSL::OCSP::Request.new
|
67
67
|
basic_response = OpenSSL::OCSP::BasicResponse.new
|
68
68
|
basic_response.copy_nonce(ocsp_request)
|
69
69
|
response_double = double("ocsp_response")
|
70
|
-
response_double.
|
71
|
-
response_double.
|
70
|
+
expect(response_double).to receive(:is_a?).and_return('OpenSSL::OCSP::Response')
|
71
|
+
expect(response_double).to receive(:basic).and_return(basic_response)
|
72
72
|
ocsp_response = R509::OCSP::Response.new(response_double)
|
73
|
-
ocsp_response.check_nonce(ocsp_request).
|
73
|
+
expect(ocsp_response.check_nonce(ocsp_request)).to eq(R509::OCSP::Request::Nonce::BOTH_ABSENT)
|
74
74
|
end
|
75
75
|
it "has a nonce in the response only" do
|
76
76
|
ocsp_request = OpenSSL::OCSP::Request.new
|
@@ -79,10 +79,10 @@ describe R509::OCSP::Response do
|
|
79
79
|
basic_response = OpenSSL::OCSP::BasicResponse.new
|
80
80
|
basic_response.copy_nonce(nonce_request)
|
81
81
|
response_double = double("ocsp_response")
|
82
|
-
response_double.
|
83
|
-
response_double.
|
82
|
+
expect(response_double).to receive(:is_a?).and_return('OpenSSL::OCSP::Response')
|
83
|
+
expect(response_double).to receive(:basic).and_return(basic_response)
|
84
84
|
ocsp_response = R509::OCSP::Response.new(response_double)
|
85
|
-
ocsp_response.check_nonce(ocsp_request).
|
85
|
+
expect(ocsp_response.check_nonce(ocsp_request)).to eq(R509::OCSP::Request::Nonce::RESPONSE_ONLY)
|
86
86
|
end
|
87
87
|
it "nonce in request and response is not equal" do
|
88
88
|
ocsp_request = OpenSSL::OCSP::Request.new
|
@@ -92,20 +92,20 @@ describe R509::OCSP::Response do
|
|
92
92
|
basic_response = OpenSSL::OCSP::BasicResponse.new
|
93
93
|
basic_response.copy_nonce(ocsp_request)
|
94
94
|
response_double = double("ocsp_response")
|
95
|
-
response_double.
|
96
|
-
response_double.
|
95
|
+
expect(response_double).to receive(:is_a?).and_return('OpenSSL::OCSP::Response')
|
96
|
+
expect(response_double).to receive(:basic).and_return(basic_response)
|
97
97
|
ocsp_response = R509::OCSP::Response.new(response_double)
|
98
|
-
ocsp_response.check_nonce(second_request).
|
98
|
+
expect(ocsp_response.check_nonce(second_request)).to eq(R509::OCSP::Request::Nonce::NOT_EQUAL)
|
99
99
|
end
|
100
100
|
it "nonce in request only" do
|
101
101
|
ocsp_request = OpenSSL::OCSP::Request.new
|
102
102
|
ocsp_request.add_nonce
|
103
103
|
basic_response = OpenSSL::OCSP::BasicResponse.new
|
104
104
|
response_double = double("ocsp_response")
|
105
|
-
response_double.
|
106
|
-
response_double.
|
105
|
+
expect(response_double).to receive(:is_a?).and_return('OpenSSL::OCSP::Response')
|
106
|
+
expect(response_double).to receive(:basic).and_return(basic_response)
|
107
107
|
ocsp_response = R509::OCSP::Response.new(response_double)
|
108
|
-
ocsp_response.check_nonce(ocsp_request).
|
108
|
+
expect(ocsp_response.check_nonce(ocsp_request)).to eq(R509::OCSP::Request::Nonce::REQUEST_ONLY)
|
109
109
|
end
|
110
110
|
|
111
111
|
end
|