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/spki_spec.rb
CHANGED
@@ -3,66 +3,66 @@ require 'stringio'
|
|
3
3
|
require 'r509/spki'
|
4
4
|
|
5
5
|
shared_examples_for "create spki with private key" do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
it "generates a spki with default digest" do
|
7
|
+
spki = R509::SPKI.new(:key => @key)
|
8
|
+
expect(spki.to_pem).not_to be_nil
|
9
|
+
spki.verify_signature
|
10
|
+
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
it "generates a spki from a pem key" do
|
13
|
+
spki = R509::SPKI.new(:key => @key.to_pem)
|
14
|
+
expect(spki.to_pem).not_to be_nil
|
15
|
+
spki.verify_signature
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
spki.verify_signature
|
18
|
+
it "generates a spki with custom digest" do
|
19
|
+
spki = R509::SPKI.new(:key => @key, :message_digest => "sha256")
|
20
|
+
expect(spki.to_pem).not_to be_nil
|
21
|
+
case
|
22
|
+
when @key.rsa?
|
23
|
+
expect(spki.signature_algorithm).to(match(/sha256/i))
|
24
|
+
when @key.dsa?
|
25
|
+
expect(spki.signature_algorithm).to(match(/sha1/i))
|
28
26
|
end
|
27
|
+
spki.verify_signature
|
28
|
+
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
it "stores the key" do
|
31
|
+
spki = R509::SPKI.new(:key => @key)
|
32
|
+
expect(spki.key).to eq(@key)
|
33
|
+
end
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
it "verifies signature" do
|
36
|
+
spki = R509::SPKI.new(:key => @key)
|
37
|
+
spki.verify_signature
|
38
|
+
end
|
39
39
|
end
|
40
40
|
|
41
41
|
shared_examples_for "spki + private key" do
|
42
42
|
it "verifies they match" do
|
43
|
-
|
43
|
+
expect { R509::SPKI.new(:key => @key, :spki => @spki) }.to_not raise_error
|
44
44
|
end
|
45
45
|
|
46
46
|
it "returns the correct signature_algorithm" do
|
47
|
-
spki = R509::SPKI.new(
|
47
|
+
spki = R509::SPKI.new(:spki => @spki, :key => @key)
|
48
48
|
case
|
49
49
|
when @key.rsa?
|
50
|
-
spki.signature_algorithm.
|
50
|
+
expect(spki.signature_algorithm).to(match(/RSA/i))
|
51
51
|
when @key.dsa?
|
52
|
-
spki.signature_algorithm.
|
52
|
+
expect(spki.signature_algorithm).to(match(/DSA/i))
|
53
53
|
when @key.ec?
|
54
|
-
spki.signature_algorithm.
|
54
|
+
expect(spki.signature_algorithm).to(match(/ecdsa/i))
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
58
|
it "errors if they don't match" do
|
59
|
-
|
59
|
+
expect { R509::SPKI.new(:key => @key, :spki => @spki2) }.to raise_error(R509::R509Error, 'Key does not match SPKI.')
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
63
|
describe R509::SPKI do
|
64
64
|
before :all do
|
65
|
-
#also known as SPKAC (signed public key and challenge)
|
65
|
+
# also known as SPKAC (signed public key and challenge)
|
66
66
|
@spki_dsa = TestFixtures::SPKI_DSA
|
67
67
|
@spki_dsa_no_verify = TestFixtures::SPKI_DSA_NO_VERIFY
|
68
68
|
@spki = TestFixtures::SPKI
|
@@ -71,10 +71,10 @@ describe R509::SPKI do
|
|
71
71
|
@spki_der = TestFixtures::SPKI_DER
|
72
72
|
end
|
73
73
|
it "raises an error if you don't provide a hash" do
|
74
|
-
expect { R509::SPKI.new("junk") }.to raise_error(ArgumentError,'Must provide a hash of options')
|
74
|
+
expect { R509::SPKI.new("junk") }.to raise_error(ArgumentError, 'Must provide a hash of options')
|
75
75
|
end
|
76
76
|
it "raises an error if you provide an empty hash" do
|
77
|
-
expect { R509::SPKI.new({}) }.to raise_error(ArgumentError,'Must provide either :spki or :key')
|
77
|
+
expect { R509::SPKI.new({}) }.to raise_error(ArgumentError, 'Must provide either :spki or :key')
|
78
78
|
end
|
79
79
|
context "rsa" do
|
80
80
|
context "no existing spki" do
|
@@ -129,127 +129,127 @@ describe R509::SPKI do
|
|
129
129
|
end
|
130
130
|
context "with existing spki" do
|
131
131
|
it "loads an RSA spki" do
|
132
|
-
spki = R509::SPKI.new(
|
133
|
-
spki.to_pem.
|
132
|
+
spki = R509::SPKI.new(:spki => @spki)
|
133
|
+
expect(spki.to_pem).to eq(@spki)
|
134
134
|
end
|
135
135
|
it "loads an spkac with newlines" do
|
136
|
-
spki = R509::SPKI.new(
|
137
|
-
spki.to_pem.
|
136
|
+
spki = R509::SPKI.new(:spki => @spki_rsa_newlines)
|
137
|
+
expect(spki.to_pem).to eq(@spki_rsa_newlines.gsub("\n", ""))
|
138
138
|
end
|
139
139
|
it "properly strips SPKAC= prefix and loads" do
|
140
|
-
spki = R509::SPKI.new(
|
141
|
-
spki.to_pem.
|
140
|
+
spki = R509::SPKI.new(:spki => "SPKAC=" + @spki)
|
141
|
+
expect(spki.to_pem).to eq(@spki)
|
142
142
|
end
|
143
143
|
end
|
144
144
|
it "returns the public key" do
|
145
|
-
spki = R509::SPKI.new(
|
146
|
-
spki.public_key.
|
145
|
+
spki = R509::SPKI.new(:spki => @spki)
|
146
|
+
expect(spki.public_key).not_to be_nil
|
147
147
|
end
|
148
148
|
it "returns pem" do
|
149
|
-
spki = R509::SPKI.new(
|
150
|
-
spki.to_pem.
|
149
|
+
spki = R509::SPKI.new(:spki => @spki)
|
150
|
+
expect(spki.to_pem).to eq(@spki)
|
151
151
|
end
|
152
152
|
it "returns der" do
|
153
|
-
spki = R509::SPKI.new(
|
154
|
-
spki.to_der.
|
153
|
+
spki = R509::SPKI.new(:spki => @spki)
|
154
|
+
expect(spki.to_der).to eq(@spki_der)
|
155
155
|
end
|
156
156
|
it "writes to pem" do
|
157
|
-
spki = R509::SPKI.new(
|
157
|
+
spki = R509::SPKI.new(:spki => @spki)
|
158
158
|
sio = StringIO.new
|
159
159
|
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
160
160
|
spki.write_pem(sio)
|
161
|
-
sio.string.
|
161
|
+
expect(sio.string).to eq(@spki)
|
162
162
|
end
|
163
163
|
it "writes to der" do
|
164
|
-
spki = R509::SPKI.new(
|
164
|
+
spki = R509::SPKI.new(:spki => @spki)
|
165
165
|
sio = StringIO.new
|
166
166
|
sio.set_encoding("BINARY") if sio.respond_to?(:set_encoding)
|
167
167
|
spki.write_der(sio)
|
168
|
-
sio.string.
|
168
|
+
expect(sio.string).to eq(@spki_der)
|
169
169
|
end
|
170
170
|
it "rsa?" do
|
171
|
-
spki = R509::SPKI.new(
|
172
|
-
spki.rsa
|
173
|
-
spki.dsa
|
171
|
+
spki = R509::SPKI.new(:spki => @spki)
|
172
|
+
expect(spki.rsa?).to eq(true)
|
173
|
+
expect(spki.dsa?).to eq(false)
|
174
174
|
end
|
175
175
|
it "returns error when asking for curve_name on non-ec" do
|
176
|
-
spki = R509::SPKI.new(
|
177
|
-
expect { spki.curve_name }.to raise_error(R509::R509Error,'Curve name is only available with EC')
|
176
|
+
spki = R509::SPKI.new(:spki => @spki)
|
177
|
+
expect { spki.curve_name }.to raise_error(R509::R509Error, 'Curve name is only available with EC')
|
178
178
|
end
|
179
179
|
it "returns RSA key algorithm for RSA" do
|
180
|
-
spki = R509::SPKI.new(
|
181
|
-
spki.key_algorithm.
|
180
|
+
spki = R509::SPKI.new(:spki => @spki)
|
181
|
+
expect(spki.key_algorithm).to eq("RSA")
|
182
182
|
end
|
183
183
|
it "gets RSA bit length" do
|
184
|
-
spki = R509::SPKI.new(
|
185
|
-
spki.bit_length.
|
186
|
-
spki.bit_strength.
|
184
|
+
spki = R509::SPKI.new(:spki => @spki)
|
185
|
+
expect(spki.bit_length).to eq(2048)
|
186
|
+
expect(spki.bit_strength).to eq(2048)
|
187
187
|
end
|
188
188
|
it "loads a DSA spkac" do
|
189
|
-
spki = R509::SPKI.new(
|
190
|
-
spki.to_pem.
|
189
|
+
spki = R509::SPKI.new(:spki => @spki_dsa)
|
190
|
+
expect(spki.to_pem).to eq(@spki_dsa)
|
191
191
|
end
|
192
192
|
it "gets DSA bit length" do
|
193
|
-
spki = R509::SPKI.new(
|
194
|
-
spki.bit_length.
|
193
|
+
spki = R509::SPKI.new(:spki => @spki_dsa)
|
194
|
+
expect(spki.bit_length).to eq(2048)
|
195
195
|
end
|
196
196
|
it "dsa?" do
|
197
|
-
spki = R509::SPKI.new(
|
198
|
-
spki.dsa
|
199
|
-
spki.rsa
|
197
|
+
spki = R509::SPKI.new(:spki => @spki_dsa)
|
198
|
+
expect(spki.dsa?).to eq(true)
|
199
|
+
expect(spki.rsa?).to eq(false)
|
200
200
|
end
|
201
201
|
it "returns DSA key algorithm for DSA" do
|
202
|
-
spki = R509::SPKI.new(
|
203
|
-
spki.key_algorithm.
|
202
|
+
spki = R509::SPKI.new(:spki => @spki_dsa)
|
203
|
+
expect(spki.key_algorithm).to eq("DSA")
|
204
204
|
end
|
205
205
|
|
206
206
|
context "elliptic curve", :ec => true do
|
207
207
|
it "loads an spkac" do
|
208
|
-
spki = R509::SPKI.new(
|
209
|
-
spki.to_pem.
|
208
|
+
spki = R509::SPKI.new(:spki => @spki_ec)
|
209
|
+
expect(spki.to_pem).to eq(@spki_ec)
|
210
210
|
end
|
211
211
|
it "returns the curve name" do
|
212
|
-
spki = R509::SPKI.new(
|
213
|
-
spki.curve_name.
|
212
|
+
spki = R509::SPKI.new(:spki => @spki_ec)
|
213
|
+
expect(spki.curve_name).to eq('secp384r1')
|
214
214
|
end
|
215
215
|
it "raises error on bit length" do
|
216
|
-
spki = R509::SPKI.new(
|
217
|
-
expect { spki.bit_length }.to raise_error(R509::R509Error,'Bit length is not available for EC at this time.')
|
216
|
+
spki = R509::SPKI.new(:spki => @spki_ec)
|
217
|
+
expect { spki.bit_length }.to raise_error(R509::R509Error, 'Bit length is not available for EC at this time.')
|
218
218
|
end
|
219
219
|
it "returns the key algorithm" do
|
220
|
-
spki = R509::SPKI.new(
|
221
|
-
spki.key_algorithm.
|
220
|
+
spki = R509::SPKI.new(:spki => @spki_ec)
|
221
|
+
expect(spki.key_algorithm).to eq("EC")
|
222
222
|
end
|
223
223
|
it "returns the public key" do
|
224
|
-
spki = R509::SPKI.new(
|
225
|
-
spki.public_key.
|
224
|
+
spki = R509::SPKI.new(:spki => @spki_ec)
|
225
|
+
expect(spki.public_key).not_to be_nil
|
226
226
|
end
|
227
227
|
it "ec?" do
|
228
|
-
spki = R509::SPKI.new(
|
229
|
-
spki.ec
|
230
|
-
spki.dsa
|
231
|
-
spki.rsa
|
228
|
+
spki = R509::SPKI.new(:spki => @spki_ec)
|
229
|
+
expect(spki.ec?).to eq(true)
|
230
|
+
expect(spki.dsa?).to eq(false)
|
231
|
+
expect(spki.rsa?).to eq(false)
|
232
232
|
end
|
233
233
|
end
|
234
234
|
|
235
235
|
context "when elliptic curve support is unavailable" do
|
236
236
|
before :all do
|
237
|
-
@ec = OpenSSL::PKey.send(:remove_const
|
237
|
+
@ec = OpenSSL::PKey.send(:remove_const, :EC) # remove EC support for test!
|
238
238
|
load('r509/ec-hack.rb')
|
239
239
|
end
|
240
240
|
after :all do
|
241
|
-
OpenSSL::PKey.send(:remove_const
|
241
|
+
OpenSSL::PKey.send(:remove_const, :EC) # remove stubbed EC
|
242
242
|
OpenSSL::PKey::EC = @ec # add the real one back
|
243
243
|
end
|
244
244
|
it "checks rsa?" do
|
245
|
-
spki = R509::SPKI.new(
|
246
|
-
spki.rsa
|
247
|
-
spki.ec
|
248
|
-
spki.dsa
|
245
|
+
spki = R509::SPKI.new(:spki => @spki)
|
246
|
+
expect(spki.rsa?).to eq(true)
|
247
|
+
expect(spki.ec?).to eq(false)
|
248
|
+
expect(spki.dsa?).to eq(false)
|
249
249
|
end
|
250
250
|
it "returns RSA key algorithm for RSA CSR" do
|
251
|
-
spki = R509::SPKI.new(
|
252
|
-
spki.key_algorithm.
|
251
|
+
spki = R509::SPKI.new(:spki => @spki)
|
252
|
+
expect(spki.key_algorithm).to eq("RSA")
|
253
253
|
end
|
254
254
|
end
|
255
255
|
end
|
data/spec/subject_spec.rb
CHANGED
@@ -9,25 +9,25 @@ describe R509::Subject do
|
|
9
9
|
|
10
10
|
it "initializes an empty subject and gets the name" do
|
11
11
|
subject = R509::Subject.new
|
12
|
-
subject.name.to_s.
|
12
|
+
expect(subject.name.to_s).to eq("")
|
13
13
|
end
|
14
14
|
it "initializes an empty subject, adds a field, and gets the name" do
|
15
15
|
subject = R509::Subject.new
|
16
16
|
subject["CN"] = "domain.com"
|
17
|
-
subject.name.to_s.
|
17
|
+
expect(subject.name.to_s).to eq("/CN=domain.com")
|
18
18
|
end
|
19
19
|
it "initializes with a subject array, and gets the name" do
|
20
20
|
subject = R509::Subject.new([["CN", "domain.com"], ["O", "my org"]])
|
21
|
-
subject.name.to_s.
|
21
|
+
expect(subject.name.to_s).to eq("/CN=domain.com/O=my org")
|
22
22
|
end
|
23
23
|
it "initializes with a subject hash, and gets the name" do
|
24
24
|
subject = R509::Subject.new(:CN => "domain.com", :O => "my org", :"1.2.3.4.4.5.6.7" => "what")
|
25
|
-
subject.name.to_s.
|
25
|
+
expect(subject.name.to_s).to eq("/CN=domain.com/O=my org/1.2.3.4.4.5.6.7=what")
|
26
26
|
end
|
27
27
|
it "initializes with a name, gets the name" do
|
28
28
|
name = OpenSSL::X509::Name.new([["CN", "domain.com"], ["O", "my org"], ["OU", "my unit"]])
|
29
29
|
subject = R509::Subject.new(name)
|
30
|
-
subject.name.to_s.
|
30
|
+
expect(subject.name.to_s).to eq("/CN=domain.com/O=my org/OU=my unit")
|
31
31
|
end
|
32
32
|
it "initializes with a subject" do
|
33
33
|
s1 = R509::Subject.new
|
@@ -35,66 +35,66 @@ describe R509::Subject do
|
|
35
35
|
s1["O"] = "my org"
|
36
36
|
|
37
37
|
s2 = R509::Subject.new(s1)
|
38
|
-
s2.name.to_s.
|
38
|
+
expect(s2.name.to_s).to eq(s1.name.to_s)
|
39
39
|
end
|
40
40
|
it "preserves order of a full subject line" do
|
41
|
-
subject = R509::Subject.new([['CN','langui.sh'],['ST','Illinois'],['L','Chicago'],['C','US'],['emailAddress','ca@langui.sh']])
|
42
|
-
subject.name.to_s.
|
41
|
+
subject = R509::Subject.new([['CN', 'langui.sh'], ['ST', 'Illinois'], ['L', 'Chicago'], ['C', 'US'], ['emailAddress', 'ca@langui.sh']])
|
42
|
+
expect(subject.name.to_s).to eq('/CN=langui.sh/ST=Illinois/L=Chicago/C=US/emailAddress=ca@langui.sh')
|
43
43
|
end
|
44
44
|
it "preserves order of a full subject line and uses to_s directly" do
|
45
|
-
subject = R509::Subject.new([['CN','langui.sh'],['ST','Illinois'],['L','Chicago'],['C','US'],['emailAddress','ca@langui.sh']])
|
46
|
-
subject.to_s.
|
45
|
+
subject = R509::Subject.new([['CN', 'langui.sh'], ['ST', 'Illinois'], ['L', 'Chicago'], ['C', 'US'], ['emailAddress', 'ca@langui.sh']])
|
46
|
+
expect(subject.to_s).to eq('/CN=langui.sh/ST=Illinois/L=Chicago/C=US/emailAddress=ca@langui.sh')
|
47
47
|
end
|
48
48
|
it "preserves order with raw OIDs, and potentially fills in known OID names" do
|
49
|
-
subject = R509::Subject.new([['2.5.4.3','common name'],['2.5.4.15','business category'],['2.5.4.7','locality'],['1.3.6.1.4.1.311.60.2.1.3','jurisdiction oid openssl typically does not know']])
|
50
|
-
subject.to_s.
|
49
|
+
subject = R509::Subject.new([['2.5.4.3', 'common name'], ['2.5.4.15', 'business category'], ['2.5.4.7', 'locality'], ['1.3.6.1.4.1.311.60.2.1.3', 'jurisdiction oid openssl typically does not know']])
|
50
|
+
expect(subject.to_s).to eq("/CN=common name/businessCategory=business category/L=locality/jurisdictionOfIncorporationCountryName=jurisdiction oid openssl typically does not know")
|
51
51
|
end
|
52
52
|
|
53
53
|
it "edits an existing subject entry" do
|
54
54
|
subject = R509::Subject.new([["CN", "domain1.com"], ["O", "my org"]])
|
55
|
-
subject.to_s.
|
55
|
+
expect(subject.to_s).to eq("/CN=domain1.com/O=my org")
|
56
56
|
|
57
57
|
subject["CN"] = "domain2.com"
|
58
|
-
subject.to_s.
|
58
|
+
expect(subject.to_s).to eq("/CN=domain2.com/O=my org")
|
59
59
|
end
|
60
60
|
|
61
61
|
it "deletes an existing subject entry" do
|
62
62
|
subject = R509::Subject.new([["CN", "domain1.com"], ["O", "my org"]])
|
63
|
-
subject.to_s.
|
63
|
+
expect(subject.to_s).to eq("/CN=domain1.com/O=my org")
|
64
64
|
|
65
65
|
subject.delete("CN")
|
66
|
-
subject.to_s.
|
66
|
+
expect(subject.to_s).to eq("/O=my org")
|
67
67
|
end
|
68
68
|
|
69
69
|
it "is empty when initialized" do
|
70
70
|
subject = R509::Subject.new
|
71
|
-
subject.empty
|
71
|
+
expect(subject.empty?).to eq(true)
|
72
72
|
subject["CN"] = "domain.com"
|
73
|
-
subject.empty
|
73
|
+
expect(subject.empty?).to eq(false)
|
74
74
|
end
|
75
75
|
|
76
76
|
it "is not empty" do
|
77
77
|
subject = R509::Subject.new([["CN", "domain1.com"]])
|
78
|
-
subject.empty
|
78
|
+
expect(subject.empty?).to eq(false)
|
79
79
|
end
|
80
80
|
|
81
81
|
it "can get a component out of the subject" do
|
82
82
|
subject = R509::Subject.new([["CN", "domain.com"]])
|
83
|
-
subject["CN"].
|
84
|
-
subject["O"].
|
83
|
+
expect(subject["CN"]).to eq("domain.com")
|
84
|
+
expect(subject["O"]).to be_nil
|
85
85
|
end
|
86
86
|
|
87
87
|
it "adds an OID" do
|
88
88
|
subject = R509::Subject.new
|
89
89
|
subject['1.3.6.1.4.1.311.60.2.1.3'] = 'jurisdiction oid openssl typically does not know'
|
90
|
-
subject['1.3.6.1.4.1.311.60.2.1.3'].
|
90
|
+
expect(subject['1.3.6.1.4.1.311.60.2.1.3']).to eq('jurisdiction oid openssl typically does not know')
|
91
91
|
end
|
92
92
|
|
93
93
|
it "deletes an OID" do
|
94
94
|
subject = R509::Subject.new([["CN", "domain.com"], ['1.3.6.1.4.1.38383.60.2.1.0.0', 'random oid']])
|
95
|
-
subject.to_s.
|
95
|
+
expect(subject.to_s).to eq("/CN=domain.com/1.3.6.1.4.1.38383.60.2.1.0.0=random oid")
|
96
96
|
subject.delete("1.3.6.1.4.1.38383.60.2.1.0.0")
|
97
|
-
subject.to_s.
|
97
|
+
expect(subject.to_s).to eq("/CN=domain.com")
|
98
98
|
end
|
99
99
|
|
100
100
|
it "fails when you instantiate with an unknown shortname" do
|
@@ -109,87 +109,87 @@ describe R509::Subject do
|
|
109
109
|
it "parses unknown OIDs out of a CSR" do
|
110
110
|
csr = R509::CSR.new(:csr => @csr_unknown_oid)
|
111
111
|
subject = R509::Subject.new(csr.subject)
|
112
|
-
subject["1.2.3.4.5.6.7.8.9.8.7.6.5.4.3.2.1.0.0"].
|
113
|
-
subject["1.3.3.543.567.32.43.335.1.1.1"].
|
114
|
-
subject["CN"].
|
112
|
+
expect(subject["1.2.3.4.5.6.7.8.9.8.7.6.5.4.3.2.1.0.0"]).to eq("random oid!")
|
113
|
+
expect(subject["1.3.3.543.567.32.43.335.1.1.1"]).to eq("another random oid!")
|
114
|
+
expect(subject["CN"]).to eq('normaldomain.com')
|
115
115
|
end
|
116
116
|
|
117
117
|
it "builds a hash" do
|
118
118
|
args = { :CN => "domain.com", :O => "my org", :"1.2.3.4.4.5.6.7" => "what" }
|
119
119
|
subject = R509::Subject.new(args)
|
120
|
-
subject.to_h.
|
120
|
+
expect(subject.to_h).to eq(args)
|
121
121
|
end
|
122
122
|
|
123
123
|
it "builds yaml" do
|
124
124
|
args = { :CN => "domain.com", :O => "my org", :"1.2.3.4.4.5.6.7" => "what" }
|
125
125
|
subject = R509::Subject.new(args)
|
126
|
-
YAML.load(subject.to_yaml).
|
126
|
+
expect(YAML.load(subject.to_yaml)).to eq(args)
|
127
127
|
end
|
128
128
|
|
129
129
|
context "dynamic getter/setter behaviors" do
|
130
130
|
it "recognizes getters for a standard subject oid" do
|
131
|
-
subject = R509::Subject.new [['CN','testCN']]
|
132
|
-
subject.CN.
|
133
|
-
subject.common_name.
|
134
|
-
subject.commonName.
|
131
|
+
subject = R509::Subject.new [['CN', 'testCN']]
|
132
|
+
expect(subject.CN).to eq('testCN')
|
133
|
+
expect(subject.common_name).to eq('testCN')
|
134
|
+
expect(subject.commonName).to eq('testCN')
|
135
135
|
end
|
136
136
|
|
137
137
|
it "recognizes setters for a standard subject oid" do
|
138
138
|
subject = R509::Subject.new
|
139
|
-
subject.CN= 'testCN'
|
140
|
-
subject.CN.
|
141
|
-
subject.common_name= 'testCN2'
|
142
|
-
subject.common_name.
|
143
|
-
subject.commonName= 'testCN3'
|
144
|
-
subject.commonName.
|
145
|
-
subject.CN.
|
146
|
-
subject.common_name.
|
139
|
+
subject.CN = 'testCN'
|
140
|
+
expect(subject.CN).to eq('testCN')
|
141
|
+
subject.common_name = 'testCN2'
|
142
|
+
expect(subject.common_name).to eq('testCN2')
|
143
|
+
subject.commonName = 'testCN3'
|
144
|
+
expect(subject.commonName).to eq('testCN3')
|
145
|
+
expect(subject.CN).to eq('testCN3')
|
146
|
+
expect(subject.common_name).to eq('testCN3')
|
147
147
|
end
|
148
148
|
|
149
149
|
it "returns properly for respond_to? with a standard subject oid" do
|
150
150
|
subject = R509::Subject.new
|
151
|
-
subject.respond_to?("CN").
|
152
|
-
subject.respond_to?("CN=").
|
153
|
-
subject.respond_to?("commonName").
|
154
|
-
subject.respond_to?("commonName=").
|
155
|
-
subject.respond_to?("common_name").
|
156
|
-
subject.respond_to?("common_name=").
|
151
|
+
expect(subject.respond_to?("CN")).to eq(true)
|
152
|
+
expect(subject.respond_to?("CN=")).to eq(true)
|
153
|
+
expect(subject.respond_to?("commonName")).to eq(true)
|
154
|
+
expect(subject.respond_to?("commonName=")).to eq(true)
|
155
|
+
expect(subject.respond_to?("common_name")).to eq(true)
|
156
|
+
expect(subject.respond_to?("common_name=")).to eq(true)
|
157
157
|
end
|
158
158
|
|
159
159
|
it "returns properly for respond_to? for an invalid method name" do
|
160
160
|
subject = R509::Subject.new
|
161
|
-
subject.respond_to?("not_a_real_method=").
|
162
|
-
subject.respond_to?("not_a_real_method").
|
161
|
+
expect(subject.respond_to?("not_a_real_method=")).to eq(false)
|
162
|
+
expect(subject.respond_to?("not_a_real_method")).to eq(false)
|
163
163
|
end
|
164
164
|
|
165
165
|
it "errors on invalid method names" do
|
166
166
|
subject = R509::Subject.new
|
167
|
-
expect { subject.random_value="assign" }.to raise_error(NoMethodError)
|
167
|
+
expect { subject.random_value = "assign" }.to raise_error(NoMethodError)
|
168
168
|
expect { subject.random_value }.to raise_error(NoMethodError)
|
169
169
|
end
|
170
170
|
|
171
171
|
it "works with an arbitrarily defined OID" do
|
172
172
|
R509::OIDMapper.register("1.4.3.2.1.2.3.6.6.6.6", "AOI", "arbitraryName")
|
173
173
|
subject = R509::Subject.new
|
174
|
-
subject.AOI= "test"
|
175
|
-
subject.AOI.
|
174
|
+
subject.AOI = "test"
|
175
|
+
expect(subject.AOI).to eq("test")
|
176
176
|
subject.arbitrary_name = "test2"
|
177
|
-
subject.arbitrary_name.
|
178
|
-
subject.arbitraryName= "test3"
|
179
|
-
subject.arbitraryName.
|
180
|
-
subject.AOI.
|
181
|
-
subject.arbitrary_name.
|
177
|
+
expect(subject.arbitrary_name).to eq("test2")
|
178
|
+
subject.arbitraryName = "test3"
|
179
|
+
expect(subject.arbitraryName).to eq("test3")
|
180
|
+
expect(subject.AOI).to eq("test3")
|
181
|
+
expect(subject.arbitrary_name).to eq("test3")
|
182
182
|
end
|
183
183
|
|
184
184
|
it "returns properly for respond_to? with a custom subject oid" do
|
185
185
|
R509::OIDMapper.register("1.4.3.2.1.2.3.7.7.7.7", "IOS", "iOperatingSystem")
|
186
186
|
subject = R509::Subject.new
|
187
|
-
subject.respond_to?("IOS").
|
188
|
-
subject.respond_to?("IOS=").
|
189
|
-
subject.respond_to?("iOperatingSystem").
|
190
|
-
subject.respond_to?("iOperatingSystem=").
|
191
|
-
subject.respond_to?("i_operating_system").
|
192
|
-
subject.respond_to?("i_operating_system=").
|
187
|
+
expect(subject.respond_to?("IOS")).to eq(true)
|
188
|
+
expect(subject.respond_to?("IOS=")).to eq(true)
|
189
|
+
expect(subject.respond_to?("iOperatingSystem")).to eq(true)
|
190
|
+
expect(subject.respond_to?("iOperatingSystem=")).to eq(true)
|
191
|
+
expect(subject.respond_to?("i_operating_system")).to eq(true)
|
192
|
+
expect(subject.respond_to?("i_operating_system=")).to eq(true)
|
193
193
|
end
|
194
194
|
|
195
195
|
end
|
@@ -204,84 +204,84 @@ describe R509::NameSanitizer do
|
|
204
204
|
it "when it has only known OIDs" do
|
205
205
|
name = OpenSSL::X509::Name.new [["C", "US"], ["ST", "Illinois"]]
|
206
206
|
array = @sanitizer.sanitize(name)
|
207
|
-
array.size.
|
208
|
-
array[0][0].
|
209
|
-
array[0][1].
|
210
|
-
array[1][0].
|
211
|
-
array[1][1].
|
207
|
+
expect(array.size).to eq(2)
|
208
|
+
expect(array[0][0]).to eq("C")
|
209
|
+
expect(array[0][1]).to eq("US")
|
210
|
+
expect(array[1][0]).to eq("ST")
|
211
|
+
expect(array[1][1]).to eq("Illinois")
|
212
212
|
end
|
213
213
|
|
214
214
|
it "when it has only unknown OIDs" do
|
215
215
|
name = OpenSSL::X509::Name.new [["1.2.3.4", "US"], ["1.2.3.5", "Illinois"]]
|
216
216
|
array = @sanitizer.sanitize(name)
|
217
|
-
array.size.
|
218
|
-
array[0][0].
|
219
|
-
array[0][1].
|
220
|
-
array[1][0].
|
221
|
-
array[1][1].
|
217
|
+
expect(array.size).to eq(2)
|
218
|
+
expect(array[0][0]).to eq("1.2.3.4")
|
219
|
+
expect(array[0][1]).to eq("US")
|
220
|
+
expect(array[1][0]).to eq("1.2.3.5")
|
221
|
+
expect(array[1][1]).to eq("Illinois")
|
222
222
|
end
|
223
223
|
|
224
224
|
it "when it has an unknown between two knowns" do
|
225
225
|
name = OpenSSL::X509::Name.new [["CN", "domain.com"], ["1.2.3.4", "US"], ["ST", "Illinois"]]
|
226
226
|
array = @sanitizer.sanitize(name)
|
227
|
-
array.size.
|
228
|
-
array[0][0].
|
229
|
-
array[0][1].
|
230
|
-
array[1][0].
|
231
|
-
array[1][1].
|
232
|
-
array[2][0].
|
233
|
-
array[2][1].
|
227
|
+
expect(array.size).to eq(3)
|
228
|
+
expect(array[0][0]).to eq("CN")
|
229
|
+
expect(array[0][1]).to eq("domain.com")
|
230
|
+
expect(array[1][0]).to eq("1.2.3.4")
|
231
|
+
expect(array[1][1]).to eq("US")
|
232
|
+
expect(array[2][0]).to eq("ST")
|
233
|
+
expect(array[2][1]).to eq("Illinois")
|
234
234
|
end
|
235
235
|
|
236
236
|
it "when it has a known between two unknowns" do
|
237
237
|
name = OpenSSL::X509::Name.new [["1.2.3.4", "domain.com"], ["C", "US"], ["1.2.3.5", "Illinois"]]
|
238
238
|
array = @sanitizer.sanitize(name)
|
239
|
-
array.size.
|
240
|
-
array[0][0].
|
241
|
-
array[0][1].
|
242
|
-
array[1][0].
|
243
|
-
array[1][1].
|
244
|
-
array[2][0].
|
245
|
-
array[2][1].
|
239
|
+
expect(array.size).to eq(3)
|
240
|
+
expect(array[0][0]).to eq("1.2.3.4")
|
241
|
+
expect(array[0][1]).to eq("domain.com")
|
242
|
+
expect(array[1][0]).to eq("C")
|
243
|
+
expect(array[1][1]).to eq("US")
|
244
|
+
expect(array[2][0]).to eq("1.2.3.5")
|
245
|
+
expect(array[2][1]).to eq("Illinois")
|
246
246
|
end
|
247
247
|
|
248
248
|
it "when a known has the same value as an unknown defined before it" do
|
249
249
|
name = OpenSSL::X509::Name.new [["1.2.3.4", "domain.com"], ["CN", "domain.com"]]
|
250
250
|
array = @sanitizer.sanitize(name)
|
251
|
-
array.size.
|
252
|
-
array[0][0].
|
253
|
-
array[0][1].
|
254
|
-
array[1][0].
|
255
|
-
array[1][1].
|
251
|
+
expect(array.size).to eq(2)
|
252
|
+
expect(array[0][0]).to eq("1.2.3.4")
|
253
|
+
expect(array[0][1]).to eq("domain.com")
|
254
|
+
expect(array[1][0]).to eq("CN")
|
255
|
+
expect(array[1][1]).to eq("domain.com")
|
256
256
|
end
|
257
257
|
|
258
258
|
it "when two unknowns have the same value" do
|
259
259
|
name = OpenSSL::X509::Name.new [["1.2.3.4", "domain.com"], ["1.2.3.5", "domain.com"]]
|
260
260
|
array = @sanitizer.sanitize(name)
|
261
|
-
array.size.
|
262
|
-
array[0][0].
|
263
|
-
array[0][1].
|
264
|
-
array[1][0].
|
265
|
-
array[1][1].
|
261
|
+
expect(array.size).to eq(2)
|
262
|
+
expect(array[0][0]).to eq("1.2.3.4")
|
263
|
+
expect(array[0][1]).to eq("domain.com")
|
264
|
+
expect(array[1][0]).to eq("1.2.3.5")
|
265
|
+
expect(array[1][1]).to eq("domain.com")
|
266
266
|
end
|
267
267
|
|
268
268
|
it "when two unknowns have the same oid and different values" do
|
269
269
|
name = OpenSSL::X509::Name.new [["1.2.3.4", "domain.com"], ["1.2.3.4", "other"]]
|
270
270
|
array = @sanitizer.sanitize(name)
|
271
|
-
array.size.
|
272
|
-
array[0][0].
|
273
|
-
array[0][1].
|
274
|
-
array[1][0].
|
275
|
-
array[1][1].
|
271
|
+
expect(array.size).to eq(2)
|
272
|
+
expect(array[0][0]).to eq("1.2.3.4")
|
273
|
+
expect(array[0][1]).to eq("domain.com")
|
274
|
+
expect(array[1][0]).to eq("1.2.3.4")
|
275
|
+
expect(array[1][1]).to eq("other")
|
276
276
|
end
|
277
277
|
|
278
278
|
it "when two unknowns have the same oid and the same value" do
|
279
279
|
name = OpenSSL::X509::Name.new [["1.2.3.4", "domain.com"], ["1.2.3.4", "domain.com"]]
|
280
280
|
array = @sanitizer.sanitize(name)
|
281
|
-
array.size.
|
282
|
-
array[0][0].
|
283
|
-
array[0][1].
|
284
|
-
array[1][0].
|
285
|
-
array[1][1].
|
281
|
+
expect(array.size).to eq(2)
|
282
|
+
expect(array[0][0]).to eq("1.2.3.4")
|
283
|
+
expect(array[0][1]).to eq("domain.com")
|
284
|
+
expect(array[1][0]).to eq("1.2.3.4")
|
285
|
+
expect(array[1][1]).to eq("domain.com")
|
286
286
|
end
|
287
287
|
end
|