certificate_authority 0.1.5 → 1.1.0

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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +26 -0
  3. data/.gitignore +6 -0
  4. data/.rspec +3 -0
  5. data/Gemfile +2 -8
  6. data/Gemfile.lock +71 -27
  7. data/README.rdoc +91 -2
  8. data/Rakefile +6 -41
  9. data/certificate_authority.gemspec +22 -83
  10. data/lib/certificate_authority/certificate.rb +139 -49
  11. data/lib/certificate_authority/certificate_revocation_list.rb +34 -14
  12. data/lib/certificate_authority/core_extensions.rb +46 -0
  13. data/lib/certificate_authority/distinguished_name.rb +64 -16
  14. data/lib/certificate_authority/extensions.rb +417 -45
  15. data/lib/certificate_authority/key_material.rb +30 -9
  16. data/lib/certificate_authority/ocsp_handler.rb +75 -5
  17. data/lib/certificate_authority/pkcs11_key_material.rb +0 -2
  18. data/lib/certificate_authority/revocable.rb +14 -0
  19. data/lib/certificate_authority/serial_number.rb +15 -2
  20. data/lib/certificate_authority/signing_request.rb +91 -0
  21. data/lib/certificate_authority/validations.rb +31 -0
  22. data/lib/certificate_authority/version.rb +3 -0
  23. data/lib/certificate_authority.rb +6 -5
  24. metadata +76 -71
  25. data/VERSION.yml +0 -5
  26. data/spec/spec_helper.rb +0 -4
  27. data/spec/units/certificate_authority_spec.rb +0 -4
  28. data/spec/units/certificate_revocation_list_spec.rb +0 -68
  29. data/spec/units/certificate_spec.rb +0 -428
  30. data/spec/units/distinguished_name_spec.rb +0 -59
  31. data/spec/units/extensions_spec.rb +0 -115
  32. data/spec/units/key_material_spec.rb +0 -100
  33. data/spec/units/ocsp_handler_spec.rb +0 -104
  34. data/spec/units/pkcs11_key_material_spec.rb +0 -41
  35. data/spec/units/serial_number_spec.rb +0 -20
  36. data/spec/units/signing_entity_spec.rb +0 -4
  37. data/spec/units/units_helper.rb +0 -1
@@ -1,428 +0,0 @@
1
- require File.dirname(__FILE__) + '/units_helper'
2
-
3
- describe CertificateAuthority::Certificate do
4
- before(:each) do
5
- @certificate = CertificateAuthority::Certificate.new
6
- end
7
-
8
- describe CertificateAuthority::SigningEntity do
9
- it "should behave as a signing entity" do
10
- @certificate.respond_to?(:is_signing_entity?).should be_true
11
- end
12
-
13
- it "should only be a signing entity if it's identified as a CA", :rfc3280 => true do
14
- @certificate.is_signing_entity?.should be_false
15
- @certificate.signing_entity = true
16
- @certificate.is_signing_entity?.should be_true
17
- end
18
-
19
- describe "Root certificates" do
20
- before(:each) do
21
- @certificate.signing_entity = true
22
- end
23
-
24
- it "should be able to be identified as a root certificate" do
25
- @certificate.is_root_entity?.should be_true
26
- end
27
-
28
- it "should only be a root certificate if the parent entity is itself", :rfc3280 => true do
29
- @certificate.parent.should == @certificate
30
- end
31
-
32
- it "should be a root certificate by default" do
33
- @certificate.is_root_entity?.should be_true
34
- end
35
-
36
- it "should be able to self-sign" do
37
- @certificate.serial_number.number = 1
38
- @certificate.subject.common_name = "chrischandler.name"
39
- @certificate.key_material.generate_key(1024)
40
- @certificate.sign!
41
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
42
- cert.subject.to_s.should == cert.issuer.to_s
43
- end
44
-
45
- it "should have the basicContraint CA:TRUE" do
46
- @certificate.serial_number.number = 1
47
- @certificate.subject.common_name = "chrischandler.name"
48
- @certificate.key_material.generate_key(1024)
49
- @certificate.sign!
50
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
51
- cert.extensions.map{|i| [i.oid,i.value] }.select{|i| i.first == "basicConstraints"}.first[1].should == "CA:TRUE"
52
- end
53
- end
54
-
55
- describe "Intermediate certificates" do
56
- before(:each) do
57
- @different_cert = CertificateAuthority::Certificate.new
58
- @different_cert.signing_entity = true
59
- @different_cert.subject.common_name = "chrischandler.name root"
60
- @different_cert.key_material.generate_key(1024)
61
- @different_cert.serial_number.number = 2
62
- @different_cert.sign! #self-signed
63
- @certificate.parent = @different_cert
64
- @certificate.signing_entity = true
65
- end
66
-
67
- it "should be able to be identified as an intermediate certificate" do
68
- @certificate.is_intermediate_entity?.should be_true
69
- end
70
-
71
- it "should not be identified as a root" do
72
- @certificate.is_root_entity?.should be_false
73
- end
74
-
75
- it "should only be an intermediate certificate if the parent is a different entity" do
76
- @certificate.parent.should_not == @certificate
77
- @certificate.parent.should_not be_nil
78
- end
79
-
80
- it "should correctly be signed by a parent certificate" do
81
- @certificate.subject.common_name = "chrischandler.name"
82
- @certificate.key_material.generate_key(1024)
83
- @certificate.signing_entity = true
84
- @certificate.serial_number.number = 1
85
- @certificate.sign!
86
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
87
- cert.subject.to_s.should_not == cert.issuer.to_s
88
- end
89
-
90
- it "should have the basicContraint CA:TRUE" do
91
- @certificate.subject.common_name = "chrischandler.name"
92
- @certificate.key_material.generate_key(1024)
93
- @certificate.signing_entity = true
94
- @certificate.serial_number.number = 3
95
- @certificate.sign!
96
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
97
- cert.extensions.map{|i| [i.oid,i.value] }.select{|i| i.first == "basicConstraints"}.first[1].should == "CA:TRUE"
98
- end
99
-
100
- end
101
-
102
- describe "Terminal certificates" do
103
- before(:each) do
104
- @different_cert = CertificateAuthority::Certificate.new
105
- @different_cert.signing_entity = true
106
- @different_cert.subject.common_name = "chrischandler.name root"
107
- @different_cert.key_material.generate_key(1024)
108
- @different_cert.serial_number.number = 1
109
- @different_cert.sign! #self-signed
110
- @certificate.parent = @different_cert
111
- end
112
-
113
- it "should not be identified as an intermediate certificate" do
114
- @certificate.is_intermediate_entity?.should be_false
115
- end
116
-
117
- it "should not be identified as a root" do
118
- @certificate.is_root_entity?.should be_false
119
- end
120
-
121
- it "should have the basicContraint CA:FALSE" do
122
- @certificate.subject.common_name = "chrischandler.name"
123
- @certificate.key_material.generate_key(1024)
124
- @certificate.signing_entity = false
125
- @certificate.serial_number.number = 1
126
- @certificate.sign!
127
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
128
- cert.extensions.map{|i| [i.oid,i.value] }.select{|i| i.first == "basicConstraints"}.first[1].should == "CA:FALSE"
129
- end
130
- end
131
-
132
-
133
- it "should be able to be identified as a root certificate" do
134
- @certificate.respond_to?(:is_root_entity?).should be_true
135
- end
136
- end #End of SigningEntity
137
-
138
- describe "Signed certificates" do
139
- before(:each) do
140
- @certificate = CertificateAuthority::Certificate.new
141
- @certificate.subject.common_name = "chrischandler.name"
142
- @certificate.key_material.generate_key(1024)
143
- @certificate.serial_number.number = 1
144
- @certificate.sign!
145
- end
146
-
147
- it "should have a PEM encoded certificate body available" do
148
- @certificate.to_pem.should_not be_nil
149
- OpenSSL::X509::Certificate.new(@certificate.to_pem).should_not be_nil
150
- end
151
- end
152
-
153
- describe "X.509 V3 Extensions on Signed Certificates" do
154
- before(:each) do
155
- @certificate = CertificateAuthority::Certificate.new
156
- @certificate.subject.common_name = "chrischandler.name"
157
- @certificate.key_material.generate_key(1024)
158
- @certificate.serial_number.number = 1
159
- @signing_profile = {
160
- "extensions" => {
161
- "subjectAltName" => {"uris" => ["www.chrischandler.name"]},
162
- "certificatePolicies" => {
163
- "policy_identifier" => "1.3.5.7",
164
- "cps_uris" => ["http://my.host.name/", "http://my.your.name/"],
165
- "user_notice" => {
166
- "explicit_text" => "Testing!", "organization" => "RSpec Test organization name", "notice_numbers" => "1,2,3,4"
167
- }
168
- }
169
- }
170
- }
171
- @certificate.sign!(@signing_profile)
172
- end
173
-
174
- describe "SubjectAltName" do
175
- before(:each) do
176
- @certificate = CertificateAuthority::Certificate.new
177
- @certificate.subject.common_name = "chrischandler.name"
178
- @certificate.key_material.generate_key(1024)
179
- @certificate.serial_number.number = 1
180
- end
181
-
182
- it "should have a subjectAltName if specified" do
183
- @certificate.sign!({"extensions" => {"subjectAltName" => {"uris" => ["www.chrischandler.name"]}}})
184
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
185
- cert.extensions.map(&:oid).include?("subjectAltName").should be_true
186
- end
187
-
188
- it "should NOT have a subjectAltName if one was not specified" do
189
- @certificate.sign!
190
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
191
- cert.extensions.map(&:oid).include?("subjectAltName").should be_false
192
- end
193
- end
194
-
195
- describe "AuthorityInfoAccess" do
196
- before(:each) do
197
- @certificate = CertificateAuthority::Certificate.new
198
- @certificate.subject.common_name = "chrischandler.name"
199
- @certificate.key_material.generate_key(1024)
200
- @certificate.serial_number.number = 1
201
- end
202
-
203
- it "should have an authority info access if specified" do
204
- @certificate.sign!({"extensions" => {"authorityInfoAccess" => {"ocsp" => ["www.chrischandler.name"]}}})
205
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
206
- cert.extensions.map(&:oid).include?("authorityInfoAccess").should be_true
207
- end
208
- end
209
-
210
- describe "CrlDistributionPoints" do
211
- before(:each) do
212
- @certificate = CertificateAuthority::Certificate.new
213
- @certificate.subject.common_name = "chrischandler.name"
214
- @certificate.key_material.generate_key(1024)
215
- @certificate.serial_number.number = 1
216
- end
217
-
218
- it "should have a crlDistributionPoint if specified" do
219
- @certificate.sign!({"extensions" => {"crlDistributionPoints" => {"uri" => ["http://crlThingy.com"]}}})
220
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
221
- cert.extensions.map(&:oid).include?("crlDistributionPoints").should be_true
222
- end
223
-
224
- it "should NOT have a crlDistributionPoint if one was not specified" do
225
- @certificate.sign!
226
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
227
- cert.extensions.map(&:oid).include?("crlDistributionPoints").should be_false
228
- end
229
- end
230
-
231
-
232
- describe "CertificatePolicies" do
233
- before(:each) do
234
- @certificate = CertificateAuthority::Certificate.new
235
- @certificate.subject.common_name = "chrischandler.name"
236
- @certificate.key_material.generate_key(1024)
237
- @certificate.serial_number.number = 1
238
- end
239
-
240
- it "should have a certificatePolicy if specified" do
241
- @certificate.sign!({
242
- "extensions" => {
243
- "certificatePolicies" => {
244
- "policy_identifier" => "1.3.5.7",
245
- "cps_uris" => ["http://my.host.name/", "http://my.your.name/"]
246
- }
247
- }
248
- })
249
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
250
- cert.extensions.map(&:oid).include?("certificatePolicies").should be_true
251
- end
252
-
253
- it "should contain a nested userNotice if specified" do
254
- pending
255
- # @certificate.sign!({
256
- # "extensions" => {
257
- # "certificatePolicies" => {
258
- # "policy_identifier" => "1.3.5.7",
259
- # "cps_uris" => ["http://my.host.name/", "http://my.your.name/"],
260
- # "user_notice" => {
261
- # "explicit_text" => "Testing!", "organization" => "RSpec Test organization name", "notice_numbers" => "1,2,3,4"
262
- # }
263
- # }
264
- # }
265
- # })
266
- # cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
267
- # cert.extensions.map(&:oid).include?("certificatePolicies").should be_true
268
- end
269
-
270
- it "should NOT include a certificatePolicy if not specified" do
271
- @certificate.sign!
272
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
273
- cert.extensions.map(&:oid).include?("certificatePolicies").should be_false
274
- end
275
- end
276
-
277
-
278
- it "should support BasicContraints" do
279
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
280
- cert.extensions.map(&:oid).include?("basicConstraints").should be_true
281
- end
282
-
283
- it "should support subjectKeyIdentifier" do
284
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
285
- cert.extensions.map(&:oid).include?("subjectKeyIdentifier").should be_true
286
- end
287
-
288
- it "should support authorityKeyIdentifier" do
289
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
290
- cert.extensions.map(&:oid).include?("authorityKeyIdentifier").should be_true
291
- end
292
-
293
- it "should order subjectKeyIdentifier before authorityKeyIdentifier" do
294
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
295
- cert.extensions.map(&:oid).select do |oid|
296
- ["subjectKeyIdentifier", "authorityKeyIdentifier"].include?(oid)
297
- end.should == ["subjectKeyIdentifier", "authorityKeyIdentifier"]
298
- end
299
-
300
- it "should support keyUsage" do
301
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
302
- cert.extensions.map(&:oid).include?("keyUsage").should be_true
303
- end
304
-
305
- it "should support extendedKeyUsage" do
306
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
307
- cert.extensions.map(&:oid).include?("extendedKeyUsage").should be_true
308
- end
309
- end
310
-
311
- describe "Signing profile" do
312
- before(:each) do
313
- @certificate = CertificateAuthority::Certificate.new
314
- @certificate.subject.common_name = "chrischandler.name"
315
- @certificate.key_material.generate_key(1024)
316
- @certificate.serial_number.number = 1
317
-
318
- @signing_profile = {
319
- "extensions" => {
320
- "basicConstraints" => {"ca" => false},
321
- "crlDistributionPoints" => {"uri" => "http://notme.com/other.crl" },
322
- "subjectKeyIdentifier" => {},
323
- "authorityKeyIdentifier" => {},
324
- "authorityInfoAccess" => {"ocsp" => ["http://youFillThisOut/ocsp/"] },
325
- "keyUsage" => {"usage" => ["digitalSignature","nonRepudiation"] },
326
- "extendedKeyUsage" => {"usage" => [ "serverAuth","clientAuth"]},
327
- "subjectAltName" => {"uris" => ["http://subdomains.youFillThisOut/"]},
328
- "certificatePolicies" => {
329
- "policy_identifier" => "1.3.5.8", "cps_uris" => ["http://my.host.name/", "http://my.your.name/"], "user_notice" => {
330
- "explicit_text" => "Explicit Text Here", "organization" => "Organization name", "notice_numbers" => "1,2,3,4"
331
- }
332
- }
333
- }
334
- }
335
- end
336
-
337
- it "should be able to sign with an optional policy hash" do
338
- @certificate.sign!(@signing_profile)
339
- end
340
-
341
- it "should support a default signing digest of SHA512" do
342
- @certificate.sign!(@signing_profile)
343
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
344
- cert.signature_algorithm.should == "sha512WithRSAEncryption"
345
- end
346
-
347
- it "should support a configurable digest algorithm" do
348
- @signing_profile.merge!({"digest" => "SHA1"})
349
- @certificate.sign!(@signing_profile)
350
- cert = OpenSSL::X509::Certificate.new(@certificate.to_pem)
351
- cert.signature_algorithm.should == "sha1WithRSAEncryption"
352
- end
353
-
354
- end
355
-
356
- describe "from_openssl" do
357
- before(:each) do
358
- @pem_cert=<<CERT
359
- -----BEGIN CERTIFICATE-----
360
- MIICFDCCAc6gAwIBAgIJAPDLgMilKuayMA0GCSqGSIb3DQEBBQUAMEgxCzAJBgNV
361
- BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMQowCAYDVQQKEwEgMRgwFgYDVQQD
362
- Ew9WZXJ5IFNtYWxsIENlcnQwHhcNMTIwNTAzMDMyODI1WhcNMTMwNTAzMDMyODI1
363
- WjBIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEKMAgGA1UEChMB
364
- IDEYMBYGA1UEAxMPVmVyeSBTbWFsbCBDZXJ0MEwwDQYJKoZIhvcNAQEBBQADOwAw
365
- OAIxAN6+33+WQ3FBMt+vMhshxOj+8W7V64pDKCJ3pVlnSn36imBWqrN0AGWX8qjv
366
- S+GzGwIDAQABo4GqMIGnMB0GA1UdDgQWBBRMUQ/HpPrAkKOufS5h+xPtEuzyWDB4
367
- BgNVHSMEcTBvgBRMUQ/HpPrAkKOufS5h+xPtEuzyWKFMpEowSDELMAkGA1UEBhMC
368
- VVMxEzARBgNVBAgTClNvbWUtU3RhdGUxCjAIBgNVBAoTASAxGDAWBgNVBAMTD1Zl
369
- cnkgU21hbGwgQ2VydIIJAPDLgMilKuayMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN
370
- AQEFBQADMQAq0CsqEChn4uf6MkXYBwaAAmS3JLmagyliJe5zM3y8dZz6Em2Ugb8o
371
- 1cCaKaHJHSg=
372
- -----END CERTIFICATE-----
373
- CERT
374
- @openssl_cert = OpenSSL::X509::Certificate.new @pem_cert
375
- @small_cert = CertificateAuthority::Certificate.from_openssl @openssl_cert
376
- end
377
-
378
- it "should reject non-Certificate arguments" do
379
- lambda { CertificateAuthority::Certificate.from_openssl "a string" }.should raise_error
380
- end
381
-
382
- it "should only be missing a private key" do
383
- @small_cert.should_not be_valid
384
- @small_cert.key_material.private_key = "data"
385
- @small_cert.should be_valid
386
- end
387
- end
388
-
389
- it "should have a distinguished name" do
390
- @certificate.distinguished_name.should_not be_nil
391
- end
392
-
393
- it "should have a serial number" do
394
- @certificate.serial_number.should_not be_nil
395
- end
396
-
397
- it "should have a subject" do
398
- @certificate.subject.should_not be_nil
399
- end
400
-
401
- it "should be able to have a parent entity" do
402
- @certificate.respond_to?(:parent).should be_true
403
- end
404
-
405
- it "should have key material" do
406
- @certificate.key_material.should_not be_nil
407
- end
408
-
409
- it "should have a not_before field" do
410
- @certificate.not_before.should_not be_nil
411
- end
412
-
413
- it "should have a not_after field" do
414
- @certificate.not_after.should_not be_nil
415
- end
416
-
417
- it "should default to one year validity" do
418
- @certificate.not_after.should < Time.now + 65 * 60 * 24 * 365 and
419
- @certificate.not_after.should > Time.now + 55 * 60 * 24 * 365
420
- end
421
-
422
- it "should be able to have a revoked at time" do
423
- @certificate.revoked?.should be_false
424
- @certificate.revoked_at = Time.now
425
- @certificate.revoked?.should be_true
426
- end
427
-
428
- end
@@ -1,59 +0,0 @@
1
- require File.dirname(__FILE__) + '/units_helper'
2
-
3
- describe CertificateAuthority::DistinguishedName do
4
- before(:each) do
5
- @distinguished_name = CertificateAuthority::DistinguishedName.new
6
- end
7
-
8
- it "should provide the standard x.509 distinguished name common attributes" do
9
- @distinguished_name.respond_to?(:cn).should be_true
10
- @distinguished_name.respond_to?(:l).should be_true
11
- @distinguished_name.respond_to?(:s).should be_true
12
- @distinguished_name.respond_to?(:o).should be_true
13
- @distinguished_name.respond_to?(:ou).should be_true
14
- @distinguished_name.respond_to?(:c).should be_true
15
- end
16
-
17
- it "should provide human-readable equivalents to the distinguished name common attributes" do
18
- @distinguished_name.respond_to?(:common_name).should be_true
19
- @distinguished_name.respond_to?(:locality).should be_true
20
- @distinguished_name.respond_to?(:state).should be_true
21
- @distinguished_name.respond_to?(:organization).should be_true
22
- @distinguished_name.respond_to?(:organizational_unit).should be_true
23
- @distinguished_name.respond_to?(:country).should be_true
24
- end
25
-
26
- it "should require a common name" do
27
- @distinguished_name.valid?.should be_false
28
- @distinguished_name.errors.size.should == 1
29
- @distinguished_name.common_name = "chrischandler.name"
30
- @distinguished_name.valid?.should be_true
31
- end
32
-
33
- it "should be convertible to an OpenSSL::X509::Name" do
34
- @distinguished_name.common_name = "chrischandler.name"
35
- @distinguished_name.to_x509_name
36
- end
37
-
38
- describe "from_openssl" do
39
- before do
40
- subject = "/CN=justincummins.name/L=on my laptop/ST=relaxed/C=as/O=programmer/OU=using this code"
41
- @name = OpenSSL::X509::Name.parse subject
42
- @dn = CertificateAuthority::DistinguishedName.from_openssl @name
43
- end
44
-
45
- it "should reject non Name objects" do
46
- lambda { CertificateAuthority::DistinguishedName.from_openssl "Not a OpenSSL::X509::Name" }.should raise_error
47
- end
48
-
49
- [:common_name, :locality, :state, :country, :organization, :organizational_unit].each do |field|
50
- it "should set the #{field} attribute" do
51
- @dn.send(field).should_not be_nil
52
- end
53
- end
54
-
55
- it "should create an equivalent object" do
56
- @dn.to_x509_name.to_s.split('/').should =~ @name.to_s.split('/')
57
- end
58
- end
59
- end
@@ -1,115 +0,0 @@
1
- require File.dirname(__FILE__) + '/units_helper'
2
-
3
- describe CertificateAuthority::Extensions do
4
- describe CertificateAuthority::Extensions::BasicContraints do
5
- it "should only allow true/false" do
6
- basic_constraints = CertificateAuthority::Extensions::BasicContraints.new
7
- basic_constraints.valid?.should be_true
8
- basic_constraints.ca = "moo"
9
- basic_constraints.valid?.should be_false
10
- end
11
-
12
- it "should respond to :path_len" do
13
- basic_constraints = CertificateAuthority::Extensions::BasicContraints.new
14
- basic_constraints.respond_to?(:path_len).should be_true
15
- end
16
-
17
- it "should raise an error if :path_len isn't a non-negative integer" do
18
- basic_constraints = CertificateAuthority::Extensions::BasicContraints.new
19
- lambda {basic_constraints.path_len = "moo"}.should raise_error
20
- lambda {basic_constraints.path_len = -1}.should raise_error
21
- lambda {basic_constraints.path_len = 1.5}.should raise_error
22
- end
23
-
24
- it "should generate a proper OpenSSL extension string" do
25
- basic_constraints = CertificateAuthority::Extensions::BasicContraints.new
26
- basic_constraints.ca = true
27
- basic_constraints.path_len = 2
28
- basic_constraints.to_s.should == "CA:true,pathlen:2"
29
- end
30
- end
31
-
32
- describe CertificateAuthority::Extensions::SubjectAlternativeName do
33
- it "should respond to :uris" do
34
- subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
35
- subjectAltName.respond_to?(:uris).should be_true
36
- end
37
-
38
- it "should require 'uris' to be an Array" do
39
- subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
40
- lambda {subjectAltName.uris = "not an array"}.should raise_error
41
- end
42
-
43
- it "should generate a proper OpenSSL extension string for URIs" do
44
- subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
45
- subjectAltName.uris = ["http://localhost.altname.example.com"]
46
- subjectAltName.to_s.should == "URI:http://localhost.altname.example.com"
47
-
48
- subjectAltName.uris = ["http://localhost.altname.example.com", "http://other.example.com"]
49
- subjectAltName.to_s.should == "URI:http://localhost.altname.example.com,URI:http://other.example.com"
50
- end
51
-
52
-
53
- it "should respond to :dns_names" do
54
- subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
55
- subjectAltName.respond_to?(:dns_names).should be_true
56
- end
57
-
58
- it "should require 'dns_names' to be an Array" do
59
- subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
60
- lambda {subjectAltName.dns_names = "not an array"}.should raise_error
61
- end
62
-
63
- it "should generate a proper OpenSSL extension string for DNS names" do
64
- subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
65
- subjectAltName.dns_names = ["localhost.altname.example.com"]
66
- subjectAltName.to_s.should == "DNS:localhost.altname.example.com"
67
-
68
- subjectAltName.dns_names = ["localhost.altname.example.com", "other.example.com"]
69
- subjectAltName.to_s.should == "DNS:localhost.altname.example.com,DNS:other.example.com"
70
- end
71
-
72
- it "should respond to :ips" do
73
- subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
74
- subjectAltName.respond_to?(:ips).should be_true
75
- end
76
-
77
- it "should require 'ips' to be an Array" do
78
- subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
79
- lambda {subjectAltName.ips = "not an array"}.should raise_error
80
- end
81
-
82
- it "should generate a proper OpenSSL extension string for IPs" do
83
- subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
84
- subjectAltName.ips = ["1.2.3.4"]
85
- subjectAltName.to_s.should == "IP:1.2.3.4"
86
-
87
- subjectAltName.ips = ["1.2.3.4", "5.6.7.8"]
88
- subjectAltName.to_s.should == "IP:1.2.3.4,IP:5.6.7.8"
89
- end
90
-
91
- it "should generate a proper OpenSSL extension string for URIs IPs and DNS names together" do
92
- subjectAltName = CertificateAuthority::Extensions::SubjectAlternativeName.new
93
- subjectAltName.ips = ["1.2.3.4"]
94
- subjectAltName.to_s.should == "IP:1.2.3.4"
95
-
96
- subjectAltName.dns_names = ["localhost.altname.example.com"]
97
- subjectAltName.to_s.should == "DNS:localhost.altname.example.com,IP:1.2.3.4"
98
-
99
- subjectAltName.dns_names = ["localhost.altname.example.com", "other.example.com"]
100
- subjectAltName.to_s.should == "DNS:localhost.altname.example.com,DNS:other.example.com,IP:1.2.3.4"
101
-
102
- subjectAltName.ips = ["1.2.3.4", "5.6.7.8"]
103
- subjectAltName.to_s.should == "DNS:localhost.altname.example.com,DNS:other.example.com,IP:1.2.3.4,IP:5.6.7.8"
104
-
105
- subjectAltName.uris = ["http://localhost.altname.example.com"]
106
- subjectAltName.to_s.should == "URI:http://localhost.altname.example.com,DNS:localhost.altname.example.com,DNS:other.example.com,IP:1.2.3.4,IP:5.6.7.8"
107
-
108
- subjectAltName.uris = ["http://localhost.altname.example.com", "http://other.altname.example.com"]
109
- subjectAltName.to_s.should == "URI:http://localhost.altname.example.com,URI:http://other.altname.example.com,DNS:localhost.altname.example.com,DNS:other.example.com,IP:1.2.3.4,IP:5.6.7.8"
110
-
111
- end
112
-
113
-
114
- end
115
- end