r509 0.8.1 → 0.9

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 (203) hide show
  1. data/README.md +343 -151
  2. data/Rakefile +26 -23
  3. data/bin/r509 +126 -112
  4. data/bin/r509-parse +24 -24
  5. data/doc/R509.html +169 -7
  6. data/doc/R509/ASN1.html +370 -0
  7. data/doc/R509/ASN1/GeneralName.html +1121 -0
  8. data/doc/R509/ASN1/GeneralNames.html +843 -0
  9. data/doc/R509/ASN1/NoticeReference.html +392 -0
  10. data/doc/R509/ASN1/PolicyInformation.html +387 -0
  11. data/doc/R509/ASN1/PolicyQualifiers.html +455 -0
  12. data/doc/R509/ASN1/UserNotice.html +386 -0
  13. data/doc/R509/{Crl.html → CRL.html} +7 -7
  14. data/doc/R509/CRL/Administrator.html +1559 -0
  15. data/doc/R509/{Crl/Parser.html → CRL/SignedList.html} +501 -210
  16. data/doc/R509/{Csr.html → CSR.html} +444 -314
  17. data/doc/R509/Cert.html +866 -617
  18. data/doc/R509/Cert/Extensions.html +52 -41
  19. data/doc/R509/Cert/Extensions/AuthorityInfoAccess.html +70 -35
  20. data/doc/R509/Cert/Extensions/AuthorityKeyIdentifier.html +387 -4
  21. data/doc/R509/Cert/Extensions/BasicConstraints.html +61 -25
  22. data/doc/R509/Cert/Extensions/CRLDistributionPoints.html +354 -0
  23. data/doc/R509/Cert/Extensions/CertificatePolicies.html +340 -0
  24. data/doc/R509/Cert/Extensions/ExtendedKeyUsage.html +440 -49
  25. data/doc/R509/Cert/Extensions/{CrlDistributionPoints.html → InhibitAnyPolicy.html} +52 -35
  26. data/doc/R509/Cert/Extensions/KeyUsage.html +247 -121
  27. data/doc/R509/Cert/Extensions/NameConstraints.html +445 -0
  28. data/doc/R509/Cert/Extensions/OCSPNoCheck.html +239 -0
  29. data/doc/R509/Cert/Extensions/PolicyConstraints.html +424 -0
  30. data/doc/R509/Cert/Extensions/SubjectAlternativeName.html +437 -62
  31. data/doc/R509/Cert/Extensions/SubjectKeyIdentifier.html +52 -10
  32. data/doc/R509/CertificateAuthority.html +4 -4
  33. data/doc/R509/CertificateAuthority/Signer.html +154 -187
  34. data/doc/R509/Config.html +6 -6
  35. data/doc/R509/Config/{CaConfig.html → CAConfig.html} +451 -348
  36. data/doc/R509/Config/{CaConfigPool.html → CAConfigPool.html} +47 -47
  37. data/doc/R509/Config/CAProfile.html +1015 -0
  38. data/doc/R509/Config/SubjectItemPolicy.html +86 -86
  39. data/doc/R509/IOHelpers.html +22 -22
  40. data/doc/R509/MessageDigest.html +14 -14
  41. data/doc/R509/NameSanitizer.html +53 -53
  42. data/doc/R509/{Ocsp.html → OCSP.html} +9 -9
  43. data/doc/R509/{Ocsp → OCSP}/Request.html +7 -7
  44. data/doc/R509/{Ocsp → OCSP}/Request/Nonce.html +56 -11
  45. data/doc/R509/{Ocsp → OCSP}/Response.html +44 -44
  46. data/doc/R509/{OidMapper.html → OIDMapper.html} +23 -39
  47. data/doc/R509/PrivateKey.html +415 -168
  48. data/doc/R509/R509Error.html +3 -3
  49. data/doc/R509/{Spki.html → SPKI.html} +354 -192
  50. data/doc/R509/Subject.html +224 -113
  51. data/doc/R509/Validity.html +27 -5
  52. data/doc/R509/Validity/Checker.html +13 -13
  53. data/doc/R509/Validity/DefaultChecker.html +13 -13
  54. data/doc/R509/Validity/DefaultWriter.html +14 -14
  55. data/doc/R509/Validity/Status.html +39 -39
  56. data/doc/R509/Validity/Writer.html +18 -18
  57. data/doc/_index.html +138 -35
  58. data/doc/class_list.html +1 -1
  59. data/doc/css/style.css +10 -0
  60. data/doc/file.README.html +368 -171
  61. data/doc/file.r509.html +92 -69
  62. data/doc/frames.html +1 -1
  63. data/doc/index.html +368 -171
  64. data/doc/method_list.html +910 -390
  65. data/doc/top-level-namespace.html +3 -3
  66. data/lib/r509.rb +32 -16
  67. data/lib/r509/asn1.rb +375 -0
  68. data/lib/r509/cert.rb +381 -364
  69. data/lib/r509/cert/extensions.rb +443 -76
  70. data/lib/r509/certificate_authority.rb +407 -0
  71. data/lib/r509/config.rb +547 -351
  72. data/lib/r509/crl.rb +336 -366
  73. data/lib/r509/csr.rb +278 -289
  74. data/lib/r509/ec-hack.rb +37 -0
  75. data/lib/r509/exceptions.rb +3 -3
  76. data/lib/r509/io_helpers.rb +44 -44
  77. data/lib/r509/message_digest.rb +53 -0
  78. data/lib/r509/ocsp.rb +80 -70
  79. data/lib/r509/oid_mapper.rb +32 -0
  80. data/lib/r509/private_key.rb +228 -0
  81. data/lib/r509/spki.rb +145 -93
  82. data/lib/r509/subject.rb +203 -110
  83. data/lib/r509/validity.rb +70 -68
  84. data/lib/r509/version.rb +2 -2
  85. data/r509.yaml +92 -69
  86. data/spec/asn1_spec.rb +402 -0
  87. data/spec/cert/extensions_spec.rb +957 -494
  88. data/spec/cert_spec.rb +382 -307
  89. data/spec/certificate_authority_spec.rb +668 -250
  90. data/spec/config_spec.rb +515 -302
  91. data/spec/crl_spec.rb +197 -198
  92. data/spec/csr_spec.rb +334 -289
  93. data/spec/fixtures.rb +247 -171
  94. data/spec/fixtures/cert1.der +0 -0
  95. data/spec/fixtures/cert1.pem +0 -0
  96. data/spec/fixtures/cert1_public_key_modulus.txt +0 -0
  97. data/spec/fixtures/cert3.p12 +0 -0
  98. data/spec/fixtures/cert3.pem +0 -0
  99. data/spec/fixtures/cert3_key.pem +0 -0
  100. data/spec/fixtures/cert3_key_des3.pem +0 -0
  101. data/spec/fixtures/cert4.pem +0 -0
  102. data/spec/fixtures/cert5.pem +0 -0
  103. data/spec/fixtures/cert6.pem +0 -0
  104. data/spec/fixtures/cert_expired.pem +0 -0
  105. data/spec/fixtures/cert_inhibit.pem +24 -0
  106. data/spec/fixtures/cert_name_constraints.pem +29 -0
  107. data/spec/fixtures/cert_not_yet_valid.pem +0 -0
  108. data/spec/fixtures/cert_ocsp_no_check.pem +18 -0
  109. data/spec/fixtures/cert_policy_constraints.pem +31 -0
  110. data/spec/fixtures/cert_san.pem +0 -0
  111. data/spec/fixtures/cert_san2.pem +0 -0
  112. data/spec/fixtures/cert_unknown_extension.pem +28 -0
  113. data/spec/fixtures/config_pool_test_minimal.yaml +11 -11
  114. data/spec/fixtures/config_test.yaml +54 -36
  115. data/spec/fixtures/config_test_dsa.yaml +35 -0
  116. data/spec/fixtures/config_test_ec.yaml +35 -0
  117. data/spec/fixtures/config_test_engine_key.yaml +5 -5
  118. data/spec/fixtures/config_test_engine_no_key_name.yaml +4 -4
  119. data/spec/fixtures/config_test_minimal.yaml +4 -4
  120. data/spec/fixtures/config_test_password.yaml +5 -5
  121. data/spec/fixtures/config_test_various.yaml +111 -74
  122. data/spec/fixtures/crl_list_file.txt +0 -0
  123. data/spec/fixtures/crl_with_reason.pem +0 -0
  124. data/spec/fixtures/csr1.der +0 -0
  125. data/spec/fixtures/csr1.pem +0 -0
  126. data/spec/fixtures/csr1_key.der +0 -0
  127. data/spec/fixtures/csr1_key.pem +0 -0
  128. data/spec/fixtures/csr1_key_encrypted_des3.pem +0 -0
  129. data/spec/fixtures/csr1_newlines.pem +0 -0
  130. data/spec/fixtures/csr1_no_begin_end.pem +0 -0
  131. data/spec/fixtures/csr1_public_key_modulus.txt +0 -0
  132. data/spec/fixtures/csr2.pem +0 -0
  133. data/spec/fixtures/csr2_key.pem +0 -0
  134. data/spec/fixtures/csr3.pem +0 -0
  135. data/spec/fixtures/csr4.pem +0 -0
  136. data/spec/fixtures/csr_dsa.pem +0 -0
  137. data/spec/fixtures/csr_invalid_signature.pem +0 -0
  138. data/spec/fixtures/dsa_key.pem +0 -0
  139. data/spec/fixtures/dsa_root.cer +28 -0
  140. data/spec/fixtures/dsa_root.key +20 -0
  141. data/spec/fixtures/ec_csr2.der +0 -0
  142. data/spec/fixtures/ec_csr2.pem +8 -0
  143. data/spec/fixtures/ec_key1.der +0 -0
  144. data/spec/fixtures/ec_key1.pem +6 -0
  145. data/spec/fixtures/ec_key1_encrypted.pem +9 -0
  146. data/spec/fixtures/ec_key2.pem +6 -0
  147. data/spec/fixtures/hmacsha1.sig +1 -0
  148. data/spec/fixtures/hmacsha512.sig +1 -0
  149. data/spec/fixtures/key4.pem +0 -0
  150. data/spec/fixtures/key4_encrypted_des3.pem +0 -0
  151. data/spec/fixtures/missing_key_identifier_ca.cer +0 -0
  152. data/spec/fixtures/missing_key_identifier_ca.key +0 -0
  153. data/spec/fixtures/ocsptest.r509.local.pem +0 -0
  154. data/spec/fixtures/ocsptest.r509.local_ocsp_request.der +0 -0
  155. data/spec/fixtures/ocsptest2.r509.local.pem +0 -0
  156. data/spec/fixtures/second_ca.cer +0 -0
  157. data/spec/fixtures/second_ca.key +0 -0
  158. data/spec/fixtures/spkac.der +0 -0
  159. data/spec/fixtures/spkac.txt +0 -0
  160. data/spec/fixtures/spkac_dsa.txt +1 -1
  161. data/spec/fixtures/spkac_dsa_no_verify.txt +1 -0
  162. data/spec/fixtures/spkac_ec.txt +1 -0
  163. data/spec/fixtures/spkac_rsa_newlines.txt +13 -0
  164. data/spec/fixtures/stca.pem +0 -0
  165. data/spec/fixtures/stca_ocsp_request.der +0 -0
  166. data/spec/fixtures/stca_ocsp_response.der +0 -0
  167. data/spec/fixtures/test1.csr +0 -0
  168. data/spec/fixtures/test_ca.cer +0 -0
  169. data/spec/fixtures/test_ca.key +0 -0
  170. data/spec/fixtures/test_ca.p12 +0 -0
  171. data/spec/fixtures/test_ca_des3.key +0 -0
  172. data/spec/fixtures/test_ca_ec.cer +14 -0
  173. data/spec/fixtures/test_ca_ec.key +6 -0
  174. data/spec/fixtures/test_ca_ec_ee.cer +22 -0
  175. data/spec/fixtures/test_ca_ec_ee.key +6 -0
  176. data/spec/fixtures/test_ca_ocsp.cer +0 -0
  177. data/spec/fixtures/test_ca_ocsp.key +0 -0
  178. data/spec/fixtures/test_ca_ocsp.p12 +0 -0
  179. data/spec/fixtures/test_ca_ocsp_chain.txt +0 -0
  180. data/spec/fixtures/test_ca_ocsp_response.der +0 -0
  181. data/spec/fixtures/test_ca_subroot.cer +0 -0
  182. data/spec/fixtures/test_ca_subroot.key +0 -0
  183. data/spec/fixtures/test_ca_subroot_ocsp.cer +0 -0
  184. data/spec/fixtures/test_ca_subroot_ocsp.key +0 -0
  185. data/spec/fixtures/test_ca_subroot_ocsp_response.der +0 -0
  186. data/spec/fixtures/unknown_oid.csr +0 -0
  187. data/spec/message_digest_spec.rb +104 -84
  188. data/spec/ocsp_spec.rb +105 -105
  189. data/spec/oid_mapper_spec.rb +21 -21
  190. data/spec/private_key_spec.rb +275 -0
  191. data/spec/r509_spec.rb +35 -0
  192. data/spec/spec_helper.rb +15 -6
  193. data/spec/spki_spec.rb +221 -142
  194. data/spec/subject_spec.rb +232 -164
  195. data/spec/validity_spec.rb +91 -91
  196. metadata +79 -25
  197. data/doc/R509/Config/CaProfile.html +0 -651
  198. data/doc/R509/Crl/Administrator.html +0 -2073
  199. data/lib/r509/certificateauthority.rb +0 -290
  200. data/lib/r509/messagedigest.rb +0 -49
  201. data/lib/r509/oidmapper.rb +0 -32
  202. data/lib/r509/privatekey.rb +0 -185
  203. data/spec/privatekey_spec.rb +0 -198
@@ -4,629 +4,1092 @@ include R509::Cert::Extensions
4
4
 
5
5
  shared_examples_for "a correctly implemented wrap_openssl_extensions" do
6
6
  before :each do
7
- @r509_extensions = R509::Cert::Extensions.wrap_openssl_extensions( @openssl_extensions )
8
-
9
- @r509_classes = [ BasicConstraints, KeyUsage, ExtendedKeyUsage,
10
- SubjectKeyIdentifier, AuthorityKeyIdentifier,
11
- SubjectAlternativeName, AuthorityInfoAccess,
12
- CrlDistributionPoints ]
13
- end
14
-
7
+ @r509_extensions = R509::Cert::Extensions.wrap_openssl_extensions( @openssl_extensions )
8
+
9
+ @r509_classes = [ BasicConstraints, KeyUsage, ExtendedKeyUsage,
10
+ SubjectKeyIdentifier, AuthorityKeyIdentifier,
11
+ SubjectAlternativeName, AuthorityInfoAccess,
12
+ CRLDistributionPoints, OCSPNoCheck ]
13
+ end
14
+
15
15
  it "should not have returned values that aren't R509 extensions" do
16
- classes = @r509_extensions.values.map { |ext| ext.class }
17
- non_r509_classes = classes.reject { |ext_class| @r509_classes.include?(ext_class) }
18
- non_r509_classes.should == []
16
+ classes = @r509_extensions.values.map { |ext| ext.class }
17
+ non_r509_classes = classes.reject { |ext_class| @r509_classes.include?(ext_class) }
18
+ non_r509_classes.should == []
19
19
  end
20
-
20
+
21
21
  it "should have returned the right number of extensions" do
22
- @r509_extensions.count.should == @wrappable_extensions.count
22
+ @r509_extensions.count.should == @wrappable_extensions.count
23
23
  end
24
-
24
+
25
25
  it "should not have returned keys improperly mapped to values" do
26
- incorrect_mappings = @r509_extensions.select { |key_class,ext| ext.class != key_class }
27
- incorrect_mappings = {} if incorrect_mappings == [] # compatibility for old versions of Ruby
28
- incorrect_mappings.should == {}
26
+ incorrect_mappings = @r509_extensions.select { |key_class,ext| ext.class != key_class }
27
+ incorrect_mappings = {} if incorrect_mappings == [] # compatibility for old versions of Ruby
28
+ incorrect_mappings.should == {}
29
29
  end
30
-
30
+
31
31
  it "should not have failed to map an implemented extension" do
32
- missing_extensions = []
33
- @wrappable_extensions.each do |openssl_ext|
34
- if (@r509_extensions.select {|r509_class,r509_ext| r509_ext.oid == openssl_ext.oid}) == {}
35
- missing_extensions << openssl_ext.oid
36
- end
32
+ missing_extensions = []
33
+ @wrappable_extensions.each do |openssl_ext|
34
+ if (@r509_extensions.select {|r509_class,r509_ext| r509_ext.oid == openssl_ext.oid}) == {}
35
+ missing_extensions << openssl_ext.oid
37
36
  end
38
-
39
- missing_extensions.should == []
37
+ end
38
+
39
+ missing_extensions.should == []
40
40
  end
41
41
  end
42
42
 
43
43
  shared_examples_for "a correctly implemented get_unknown_extensions" do
44
44
  it "should not have returned values that are R509 extensions" do
45
- R509::Cert::Extensions.get_unknown_extensions( @openssl_extensions ).should == @unknown_extensions
45
+ R509::Cert::Extensions.get_unknown_extensions( @openssl_extensions ).should == @unknown_extensions
46
46
  end
47
47
  end
48
48
 
49
- shared_examples_for "a correct R509 BasicConstraints object" do
50
- before :all do
51
- extension_name = "basicConstraints"
52
- klass = BasicConstraints
53
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
54
- @r509_ext = klass.new( openssl_ext )
55
- end
49
+ shared_examples_for "a correct R509 BasicConstraints object" do |critical|
50
+ before :all do
51
+ extension_name = "basicConstraints"
52
+ klass = BasicConstraints
53
+ ef = OpenSSL::X509::ExtensionFactory.new
54
+ openssl_ext = ef.create_extension( extension_name, @extension_value , critical)
55
+ @r509_ext = klass.new( openssl_ext )
56
+ end
56
57
 
57
- it "is_ca? should correctly report whether it's a CA certificate" do
58
- @r509_ext.is_ca?.should == @is_ca
59
- end
58
+ it "is_ca? should correctly report whether it's a CA certificate (critical:#{critical})" do
59
+ @r509_ext.is_ca?.should == @is_ca
60
+ end
60
61
 
61
- it "the path length should be correct" do
62
- @r509_ext.path_length.should == @pathlen
63
- end
62
+ it "the path length should be correct (critical:#{critical})" do
63
+ @r509_ext.path_length.should == @pathlen
64
+ end
64
65
 
65
- it "allows_sub_ca? should correctly report whether its path length allows it to issue CA certs" do
66
- @r509_ext.allows_sub_ca?.should == @allows_sub_ca
67
- end
66
+ it "allows_sub_ca? should correctly report whether its path length allows it to issue CA certs (critical:#{critical})" do
67
+ @r509_ext.allows_sub_ca?.should == @allows_sub_ca
68
+ end
69
+
70
+ it "reports #critical? properly" do
71
+ @r509_ext.critical?.should == critical
72
+ end
68
73
  end
69
74
 
70
- shared_examples_for "a correct R509 KeyUsage object" do
71
- before :all do
72
- extension_name = "keyUsage"
73
- klass = KeyUsage
74
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
75
- @r509_ext = klass.new( openssl_ext )
76
- end
75
+ shared_examples_for "a correct R509 KeyUsage object" do |critical|
76
+ before :each do
77
+ extension_name = "keyUsage"
78
+ klass = KeyUsage
79
+ ef = OpenSSL::X509::ExtensionFactory.new
80
+ openssl_ext = ef.create_extension( extension_name, @extension_value, critical )
81
+ @r509_ext = klass.new( openssl_ext )
82
+ end
77
83
 
78
- it "allowed_uses should be non-nil" do
79
- @r509_ext.allowed_uses.should_not == nil
80
- end
84
+ it "allowed_uses should be non-nil critical:#{critical}" do
85
+ @r509_ext.allowed_uses.should_not == nil
86
+ end
81
87
 
82
- it "allowed_uses should be correct" do
83
- @r509_ext.allowed_uses.should == @allowed_uses
84
- end
88
+ it "allowed_uses should be correct critical:#{critical}" do
89
+ @r509_ext.allowed_uses.should == @allowed_uses
90
+ end
85
91
 
86
- it "the individual allowed-use functions should be correct" do
87
- @r509_ext.digital_signature?.should == @allowed_uses.include?( KeyUsage::AU_DIGITAL_SIGNATURE )
88
- @r509_ext.non_repudiation?.should == @allowed_uses.include?( KeyUsage::AU_NON_REPUDIATION )
89
- @r509_ext.key_encipherment?.should == @allowed_uses.include?( KeyUsage::AU_KEY_ENCIPHERMENT )
90
- @r509_ext.data_encipherment?.should == @allowed_uses.include?( KeyUsage::AU_DATA_ENCIPHERMENT )
91
- @r509_ext.key_agreement?.should == @allowed_uses.include?( KeyUsage::AU_KEY_AGREEMENT )
92
- @r509_ext.certificate_sign?.should == @allowed_uses.include?( KeyUsage::AU_CERTIFICATE_SIGN )
93
- @r509_ext.crl_sign?.should == @allowed_uses.include?( KeyUsage::AU_CRL_SIGN )
94
- @r509_ext.encipher_only?.should == @allowed_uses.include?( KeyUsage::AU_ENCIPHER_ONLY )
95
- @r509_ext.decipher_only?.should == @allowed_uses.include?( KeyUsage::AU_DECIPHER_ONLY )
92
+ it "the individual allowed-use functions should be correct critical:#{critical}" do
93
+ @r509_ext.digital_signature?.should == @allowed_uses.include?( KeyUsage::AU_DIGITAL_SIGNATURE )
94
+ @r509_ext.non_repudiation?.should == @allowed_uses.include?( KeyUsage::AU_NON_REPUDIATION )
95
+ @r509_ext.key_encipherment?.should == @allowed_uses.include?( KeyUsage::AU_KEY_ENCIPHERMENT )
96
+ @r509_ext.data_encipherment?.should == @allowed_uses.include?( KeyUsage::AU_DATA_ENCIPHERMENT )
97
+ @r509_ext.key_agreement?.should == @allowed_uses.include?( KeyUsage::AU_KEY_AGREEMENT )
98
+ @r509_ext.key_cert_sign?.should == @allowed_uses.include?( KeyUsage::AU_KEY_CERT_SIGN )
99
+ @r509_ext.crl_sign?.should == @allowed_uses.include?( KeyUsage::AU_CRL_SIGN )
100
+ @r509_ext.encipher_only?.should == @allowed_uses.include?( KeyUsage::AU_ENCIPHER_ONLY )
101
+ @r509_ext.decipher_only?.should == @allowed_uses.include?( KeyUsage::AU_DECIPHER_ONLY )
102
+ end
103
+
104
+ it "the #allows? method should work critical:#{critical}" do
105
+ @allowed_uses.each do |au|
106
+ @r509_ext.allows?(au).should == true
96
107
  end
108
+ end
109
+
110
+ it "reports #critical? properly" do
111
+ @r509_ext.critical?.should == critical
112
+ end
97
113
  end
98
114
 
99
- shared_examples_for "a correct R509 ExtendedKeyUsage object" do
100
- before :all do
101
- extension_name = "extendedKeyUsage"
102
- klass = ExtendedKeyUsage
103
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
104
- @r509_ext = klass.new( openssl_ext )
105
- end
115
+ shared_examples_for "a correct R509 ExtendedKeyUsage object" do |critical|
116
+ before :all do
117
+ extension_name = "extendedKeyUsage"
118
+ klass = ExtendedKeyUsage
119
+ ef = OpenSSL::X509::ExtensionFactory.new
120
+ openssl_ext = ef.create_extension( extension_name, @extension_value , critical )
121
+ @r509_ext = klass.new( openssl_ext )
122
+ end
106
123
 
107
- it "allowed_uses should be non-nil" do
108
- @r509_ext.allowed_uses.should_not == nil
109
- end
124
+ it "allowed_uses should be non-nil critical:#{critical}" do
125
+ @r509_ext.allowed_uses.should_not == nil
126
+ end
110
127
 
111
- it "allowed_uses should be correct" do
112
- @r509_ext.allowed_uses.should == @allowed_uses
113
- end
128
+ it "allowed_uses should be correct critical:#{critical}" do
129
+ @r509_ext.allowed_uses.should == @allowed_uses
130
+ end
131
+
132
+ it "the individual allowed-use functions should be correct critical:#{critical}" do
133
+ @r509_ext.web_server_authentication?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_WEB_SERVER_AUTH )
134
+ @r509_ext.web_client_authentication?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_WEB_CLIENT_AUTH )
135
+ @r509_ext.code_signing?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_CODE_SIGNING )
136
+ @r509_ext.email_protection?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_EMAIL_PROTECTION )
137
+ @r509_ext.ocsp_signing?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_OCSP_SIGNING )
138
+ @r509_ext.time_stamping?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_TIME_STAMPING )
139
+ @r509_ext.any_extended_key_usage?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_ANY_EXTENDED_KEY_USAGE )
140
+ end
114
141
 
115
- it "the individual allowed-use functions should be correct" do
116
- @r509_ext.web_server_authentication?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_WEB_SERVER_AUTH )
117
- @r509_ext.web_client_authentication?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_WEB_CLIENT_AUTH )
118
- @r509_ext.code_signing?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_CODE_SIGNING )
119
- @r509_ext.email_protection?.should == @allowed_uses.include?( ExtendedKeyUsage::AU_EMAIL_PROTECTION )
142
+ it "the #allows? method should work critical:#{critical}" do
143
+ @allowed_uses.each do |au|
144
+ @r509_ext.allows?(au).should == true
120
145
  end
146
+ end
147
+
148
+ it "reports #critical? properly" do
149
+ @r509_ext.critical?.should == critical
150
+ end
121
151
  end
122
152
 
123
153
  shared_examples_for "a correct R509 SubjectKeyIdentifier object" do
124
- before :all do
125
- extension_name = "subjectKeyIdentifier"
126
- klass = SubjectKeyIdentifier
127
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
128
- @r509_ext = klass.new( openssl_ext )
129
- end
154
+ before :all do
155
+ extension_name = "subjectKeyIdentifier"
156
+ klass = SubjectKeyIdentifier
157
+ openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
158
+ @r509_ext = klass.new( openssl_ext )
159
+ end
130
160
 
131
- it "key should be correct" do
132
- @r509_ext.key.should == @key
133
- end
161
+ it "key should be correct" do
162
+ @r509_ext.key.should == @key
163
+ end
134
164
  end
135
165
 
136
166
  shared_examples_for "a correct R509 AuthorityKeyIdentifier object" do
137
- before :all do
138
- extension_name = "authorityKeyIdentifier"
139
- klass = AuthorityKeyIdentifier
140
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
141
- @r509_ext = klass.new( openssl_ext )
142
- end
167
+ before :all do
168
+ extension_name = "authorityKeyIdentifier"
169
+ klass = AuthorityKeyIdentifier
170
+ ef = OpenSSL::X509::ExtensionFactory.new
171
+ ef.issuer_certificate = OpenSSL::X509::Certificate.new TestFixtures::TEST_CA_CERT
172
+ openssl_ext = ef.create_extension( "authorityKeyIdentifier", @extension_value )
173
+ @r509_ext = klass.new( openssl_ext )
174
+ end
175
+
176
+ it "has the expected type" do
177
+ @r509_ext.oid.should == "authorityKeyIdentifier"
178
+ end
143
179
 
144
- #TODO
180
+ it "contains the key identifier" do
181
+ @r509_ext.key_identifier.should == "79:75:BB:84:3A:CB:2C:DE:7A:09:BE:31:1B:43:BC:1C:2A:4D:53:58"
182
+ end
183
+ it "parses the authority cert issuer and serial number" do
184
+ @r509_ext.authority_cert_issuer.value.to_s.should == "/C=US/ST=Illinois/L=Chicago/O=Ruby CA Project/CN=Test CA"
185
+ @r509_ext.authority_cert_serial_number.should == 'FF:D9:C7:0B:87:37:D1:94'
186
+ end
145
187
  end
146
188
 
147
- shared_examples_for "a correct R509 SubjectAlternativeName object" do
148
- before :all do
149
- extension_name = "subjectAltName"
150
- klass = SubjectAlternativeName
151
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
152
- @r509_ext = klass.new( openssl_ext )
153
- end
189
+ shared_examples_for "a correct R509 SubjectAlternativeName object" do |critical|
190
+ before :all do
191
+ extension_name = "subjectAltName"
192
+ klass = SubjectAlternativeName
193
+ ef = OpenSSL::X509::ExtensionFactory.new
194
+ ef.config = OpenSSL::Config.parse(@conf)
195
+ openssl_ext = ef.create_extension( extension_name, @extension_value , critical )
196
+ @r509_ext = klass.new( openssl_ext )
197
+ end
154
198
 
155
- it "dns_names should be correct" do
156
- @r509_ext.dns_names.should == @dns_names
157
- end
199
+ it "dns_names should be correct critical:#{critical}" do
200
+ @r509_ext.dns_names.should == @dns_names
201
+ end
158
202
 
159
- it "ip_addresses should be correct" do
160
- @r509_ext.ip_addresses.should == @ip_addresses
161
- end
203
+ it "ip_addresses should be correct critical:#{critical}" do
204
+ @r509_ext.ip_addresses.should == @ip_addresses
205
+ end
162
206
 
163
- it "uris should be correct" do
164
- @r509_ext.uris.should == @uris
165
- end
207
+ it "rfc_822names should be correct critical:#{critical}" do
208
+ @r509_ext.rfc_822_names.should == @rfc_822_names
209
+ end
210
+
211
+ it "uris should be correct critical:#{critical}" do
212
+ @r509_ext.uris.should == @uris
213
+ end
214
+
215
+ it "dirNames should be correct critical:#{critical}" do
216
+ @r509_ext.directory_names.size.should == @directory_names.size
217
+ end
218
+
219
+ it "ordered should be correct critical:#{critical}" do
220
+ @r509_ext.names.size.should == @dns_names.size + @ip_addresses.size + @rfc_822_names.size + @uris.size + @directory_names.size
221
+ end
222
+
223
+ it "reports #critical? properly" do
224
+ @r509_ext.critical?.should == critical
225
+ end
166
226
  end
167
227
 
168
- shared_examples_for "a correct R509 AuthorityInfoAccess object" do
169
- before :all do
170
- extension_name = "authorityInfoAccess"
171
- klass = AuthorityInfoAccess
172
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
173
- @r509_ext = klass.new( openssl_ext )
174
- end
228
+ shared_examples_for "a correct R509 AuthorityInfoAccess object" do |critical|
229
+ before :all do
230
+ extension_name = "authorityInfoAccess"
231
+ klass = AuthorityInfoAccess
232
+ ef = OpenSSL::X509::ExtensionFactory.new
233
+ openssl_ext = ef.create_extension( extension_name, @extension_value, critical )
234
+ @r509_ext = klass.new( openssl_ext )
235
+ end
175
236
 
176
- it "ca_issuers_uri should be correct" do
177
- @r509_ext.ca_issuers_uris.should == @ca_issuers_uris
178
- end
237
+ it "ca_issuers_uri should be correct critical:#{critical}" do
238
+ @r509_ext.ca_issuers.uris.should == @ca_issuers_uris
239
+ end
179
240
 
180
- it "ocsp_uri should be correct" do
181
- @r509_ext.ocsp_uris.should == @ocsp_uris
182
- end
241
+ it "ocsp_uri should be correct critical:#{critical}" do
242
+ @r509_ext.ocsp.uris.should == @ocsp_uris
243
+ end
244
+
245
+ it "reports #critical? properly" do
246
+ @r509_ext.critical?.should == critical
247
+ end
183
248
  end
184
249
 
185
- shared_examples_for "a correct R509 CrlDistributionPoints object" do
186
- before :all do
187
- extension_name = "crlDistributionPoints"
188
- klass = CrlDistributionPoints
189
- openssl_ext = OpenSSL::X509::Extension.new( extension_name, @extension_value )
190
- @r509_ext = klass.new( openssl_ext )
191
- end
250
+ shared_examples_for "a correct R509 CRLDistributionPoints object" do |critical|
251
+ before :all do
252
+ extension_name = "crlDistributionPoints"
253
+ klass = CRLDistributionPoints
254
+ ef = OpenSSL::X509::ExtensionFactory.new
255
+ openssl_ext = ef.create_extension( extension_name, @extension_value , critical )
256
+ @r509_ext = klass.new( openssl_ext )
257
+ end
192
258
 
193
- it "crl_uri should be correct" do
194
- @r509_ext.crl_uris.should == @crl_uris
195
- end
259
+ it "crl_uri should be correct critical:#{critical}" do
260
+ @r509_ext.crl.uris.should == @crl_uris
261
+ end
262
+
263
+ it "reports #critical? properly" do
264
+ @r509_ext.critical?.should == critical
265
+ end
266
+ end
267
+
268
+ shared_examples_for "a correct R509 OCSPNoCheck object" do |critical|
269
+ before :all do
270
+ extension_name = "noCheck"
271
+ klass = OCSPNoCheck
272
+ ef = OpenSSL::X509::ExtensionFactory.new
273
+ openssl_ext = ef.create_extension( extension_name, "irrelevant", critical)
274
+ @r509_ext = klass.new( openssl_ext )
275
+ end
276
+
277
+ it "has the expected type" do
278
+ @r509_ext.oid.should == "noCheck"
279
+ end
280
+
281
+ it "reports #critical? properly" do
282
+ @r509_ext.critical?.should == critical
283
+ end
196
284
  end
197
285
 
286
+ shared_examples_for "a correct R509 CertificatePolicies object" do
287
+ before :all do
288
+ klass = CertificatePolicies
289
+ openssl_ext = OpenSSL::X509::Extension.new @policy_data
290
+ @r509_ext = klass.new( openssl_ext )
291
+ end
198
292
 
199
- describe R509::Cert::Extensions do
200
- include R509::Cert::Extensions
201
-
202
- context "Class functions" do
203
- context "#wrap_openssl_extensions and #get_unknown_extensions" do
204
- context "with no extensions" do
205
- before :each do
206
- @wrappable_extensions = []
207
- @unknown_extensions = []
208
-
209
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
210
- end
211
-
212
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
213
- it_should_behave_like "a correctly implemented get_unknown_extensions"
214
- end
215
-
216
- context "with one implemented extension" do
217
- before :each do
218
- @wrappable_extensions = []
219
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
220
-
221
- @unknown_extensions = []
222
-
223
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
224
- end
225
-
226
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
227
- it_should_behave_like "a correctly implemented get_unknown_extensions"
228
- end
229
-
230
- context "with all implemented extensions" do
231
- before :each do
232
- @wrappable_extensions = []
233
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
234
- @wrappable_extensions << OpenSSL::X509::Extension.new( "keyUsage", KeyUsage::AU_DIGITAL_SIGNATURE )
235
- @wrappable_extensions << OpenSSL::X509::Extension.new( "extendedKeyUsage", ExtendedKeyUsage::AU_WEB_SERVER_AUTH )
236
- @wrappable_extensions << OpenSSL::X509::Extension.new( "subjectKeyIdentifier", "00:11:22:33:44:55:66:77:88:99:00:AA:BB:CC:DD:EE:FF:00:11:22" )
237
- @wrappable_extensions << OpenSSL::X509::Extension.new( "authorityKeyIdentifier", "keyid:always" )
238
- @wrappable_extensions << OpenSSL::X509::Extension.new( "subjectAltName", "DNS:www.test.local" )
239
- @wrappable_extensions << OpenSSL::X509::Extension.new( "authorityInfoAccess", "CA Issuers - URI:http://www.test.local" )
240
- @wrappable_extensions << OpenSSL::X509::Extension.new( "crlDistributionPoints", "URI:http://www.test.local" )
241
-
242
- @unknown_extensions = []
243
-
244
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
245
- end
246
-
247
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
248
- it_should_behave_like "a correctly implemented get_unknown_extensions"
249
- end
250
-
251
- context "with an unimplemented extension" do
252
- before :each do
253
- @wrappable_extensions = []
254
-
255
- @unknown_extensions = []
256
- @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
257
-
258
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
259
- end
260
-
261
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
262
- it_should_behave_like "a correctly implemented get_unknown_extensions"
263
- end
264
-
265
- context "with implemented and unimplemented extensions" do
266
- before :each do
267
- @wrappable_extensions = []
268
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
269
-
270
- @unknown_extensions = []
271
- @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
272
-
273
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
274
- end
275
-
276
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
277
- it_should_behave_like "a correctly implemented get_unknown_extensions"
278
- end
279
-
280
- context "with multiple extensions of an implemented type" do
281
- before :each do
282
- @wrappable_extensions = []
283
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
284
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:1" )
285
-
286
- @unknown_extensions = []
287
- @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
288
-
289
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
290
- end
291
-
292
- it "should raise an ArgumentError for #wrap_openssl_extensions" do
293
- expect {
294
- R509::Cert::Extensions.wrap_openssl_extensions( @openssl_extensions )
295
- }.to raise_error(ArgumentError)
296
- end
297
- it_should_behave_like "a correctly implemented get_unknown_extensions"
298
- end
299
-
300
- context "with multiple extensions of an unimplemented type" do
301
- before :each do
302
- @wrappable_extensions = []
303
- @wrappable_extensions << OpenSSL::X509::Extension.new( "basicConstraints", "CA:TRUE;pathlen:0" )
304
-
305
- @unknown_extensions = []
306
- @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
307
- @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www2.test.local" )
308
-
309
- @openssl_extensions = @wrappable_extensions + @unknown_extensions
310
- end
311
-
312
- it_should_behave_like "a correctly implemented wrap_openssl_extensions"
313
- it_should_behave_like "a correctly implemented get_unknown_extensions"
314
- end
315
- end
293
+ it "should correctly parse the data" do
294
+ @r509_ext.policies.count.should == 1
295
+ @r509_ext.policies[0].policy_identifier.should == "2.16.840.1.12345.1.2.3.4.1"
296
+ @r509_ext.policies[0].policy_qualifiers.cps_uris.should == ["http://example.com/cps", "http://other.com/cps"]
297
+ end
298
+ end
299
+
300
+ shared_examples_for "a correct R509 InhibitAnyPolicy object" do |critical|
301
+ before :all do
302
+ extension_name = "inhibitAnyPolicy"
303
+ klass = InhibitAnyPolicy
304
+ ef = OpenSSL::X509::ExtensionFactory.new
305
+ openssl_ext = ef.create_extension( extension_name, @skip_certs.to_s,critical)
306
+ @r509_ext = klass.new( openssl_ext )
307
+ end
308
+
309
+ it "should parse the integer value out of the extension" do
310
+ @r509_ext.skip_certs.should == @skip_certs
311
+ end
312
+
313
+ it "reports #critical? properly" do
314
+ @r509_ext.critical?.should == critical
315
+ end
316
+ end
317
+
318
+ shared_examples_for "a correct R509 PolicyConstraints object" do |critical|
319
+ before :all do
320
+ extension_name = "policyConstraints"
321
+ klass = PolicyConstraints
322
+ ef = OpenSSL::X509::ExtensionFactory.new
323
+ openssl_ext = ef.create_extension( extension_name, @extension_value, critical)
324
+ @r509_ext = klass.new( openssl_ext )
325
+ end
326
+
327
+ it "should have the expected require policy" do
328
+ @r509_ext.require_explicit_policy.should == @require_explicit_policy
329
+ end
330
+ it "should have the expected inhibit mapping" do
331
+ @r509_ext.inhibit_policy_mapping.should == @inhibit_policy_mapping
332
+ end
333
+ end
334
+
335
+ shared_examples_for "a correct R509 NameConstraints object" do |critical|
336
+ before :all do
337
+ extension_name = "nameConstraints"
338
+ klass = NameConstraints
339
+ ef = OpenSSL::X509::ExtensionFactory.new
340
+ ef.config = OpenSSL::Config.parse(@conf)
341
+ openssl_ext = ef.create_extension( extension_name, @extension_value, critical)
342
+ @r509_ext = klass.new( openssl_ext )
343
+ end
344
+
345
+ it "should have the permitted names" do
346
+ @permitted_names.each_with_index do |name,index|
347
+ @r509_ext.permitted_names[index].tag.should == name[:tag]
348
+ @r509_ext.permitted_names[index].value.should == name[:value]
316
349
  end
350
+ end
351
+ it "should have the excluded names" do
352
+ @excluded_names.each_with_index do |name,index|
353
+ @r509_ext.excluded_names[index].tag.should == name[:tag]
354
+ @r509_ext.excluded_names[index].value.should == name[:value]
355
+ end
356
+ end
357
+ end
317
358
 
318
- context "BasicConstraints" do
319
- context "with constraints for a CA certificate" do
320
- before :all do
321
- @extension_value = "CA:TRUE;pathlen:1"
322
- @is_ca = true
323
- @pathlen = 1
324
- @allows_sub_ca = true
325
- end
359
+ describe R509::Cert::Extensions do
360
+ include R509::Cert::Extensions
326
361
 
327
- it_should_behave_like "a correct R509 BasicConstraints object"
362
+ context "Class functions" do
363
+ context "#wrap_openssl_extensions and #get_unknown_extensions" do
364
+ context "with no extensions" do
365
+ before :each do
366
+ @wrappable_extensions = []
367
+ @unknown_extensions = []
368
+
369
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
328
370
  end
329
371
 
330
- context "with constraints for a sub-CA certificate" do
331
- before :all do
332
- @extension_value = "CA:TRUE;pathlen:0"
333
- @is_ca = true
334
- @pathlen = 0
335
- @allows_sub_ca = false
336
- end
372
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
373
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
374
+ end
375
+
376
+ context "with one implemented extension" do
377
+ before :each do
378
+ @wrappable_extensions = []
379
+ ef = OpenSSL::X509::ExtensionFactory.new
380
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:0" )
381
+
382
+ @unknown_extensions = []
337
383
 
338
- it_should_behave_like "a correct R509 BasicConstraints object"
384
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
339
385
  end
340
386
 
341
- context "with constraints for a non-CA certificate" do
342
- before :all do
343
- @extension_value = "CA:FALSE"
344
- @is_ca = false
345
- @pathlen = nil
346
- @allows_sub_ca = false
347
- end
387
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
388
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
389
+ end
348
390
 
349
- it_should_behave_like "a correct R509 BasicConstraints object"
391
+ context "with all implemented extensions" do
392
+ before :each do
393
+ @wrappable_extensions = []
394
+ ef = OpenSSL::X509::ExtensionFactory.new
395
+ ef.issuer_certificate = OpenSSL::X509::Certificate.new TestFixtures::TEST_CA_CERT
396
+ ef.subject_certificate = OpenSSL::X509::Certificate.new TestFixtures::TEST_CA_CERT
397
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:0", true )
398
+ @wrappable_extensions << ef.create_extension( "keyUsage", KeyUsage::AU_DIGITAL_SIGNATURE )
399
+ @wrappable_extensions << ef.create_extension( "extendedKeyUsage", ExtendedKeyUsage::AU_WEB_SERVER_AUTH )
400
+ @wrappable_extensions << ef.create_extension( "subjectKeyIdentifier", "hash" )
401
+ @wrappable_extensions << ef.create_extension( "authorityKeyIdentifier", "keyid:always" )
402
+ @wrappable_extensions << ef.create_extension( "subjectAltName", "DNS:www.test.local" )
403
+ @wrappable_extensions << ef.create_extension( "authorityInfoAccess", "caIssuers;URI:http://www.test.local" )
404
+ @wrappable_extensions << ef.create_extension( "crlDistributionPoints", "URI:http://www.test.local" )
405
+
406
+ @unknown_extensions = []
407
+
408
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
350
409
  end
351
- end
352
410
 
353
- context "KeyUsage" do
354
- context "with one allowed use" do
355
- before :all do
356
- @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE ]
357
- @extension_value = @allowed_uses.join( ", " )
358
- end
411
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
412
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
413
+ end
414
+
415
+ context "with an unimplemented extension" do
416
+ before :each do
417
+ @wrappable_extensions = []
418
+
419
+ @unknown_extensions = []
420
+ @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
359
421
 
360
- it_should_behave_like "a correct R509 KeyUsage object"
422
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
361
423
  end
362
424
 
363
- context "with some allowed uses" do
364
- before :all do
365
- # this spec and the one below alternate the uses
366
- @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE, KeyUsage::AU_KEY_ENCIPHERMENT, KeyUsage::AU_KEY_AGREEMENT, KeyUsage::AU_CRL_SIGN, KeyUsage::AU_DECIPHER_ONLY ]
367
- @extension_value = @allowed_uses.join( ", " )
368
- end
425
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
426
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
427
+ end
428
+
429
+ context "with implemented and unimplemented extensions" do
430
+ before :each do
431
+ @wrappable_extensions = []
432
+ ef = OpenSSL::X509::ExtensionFactory.new
433
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:0" )
369
434
 
370
- it_should_behave_like "a correct R509 KeyUsage object"
435
+ @unknown_extensions = []
436
+ @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
437
+
438
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
371
439
  end
372
440
 
373
- context "with some different allowed uses" do
374
- before :all do
375
- @allowed_uses = [ KeyUsage::AU_NON_REPUDIATION, KeyUsage::AU_DATA_ENCIPHERMENT, KeyUsage::AU_CERTIFICATE_SIGN, KeyUsage::AU_ENCIPHER_ONLY ]
376
- @extension_value = @allowed_uses.join( ", " )
377
- end
441
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
442
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
443
+ end
444
+
445
+ context "with multiple extensions of an implemented type" do
446
+ before :each do
447
+ @wrappable_extensions = []
448
+ ef = OpenSSL::X509::ExtensionFactory.new
449
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:0" )
450
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:1" )
451
+
452
+ @unknown_extensions = []
453
+ @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
378
454
 
379
- it_should_behave_like "a correct R509 KeyUsage object"
455
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
380
456
  end
381
457
 
382
- context "with all allowed uses" do
383
- before :all do
384
- @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE, KeyUsage::AU_KEY_ENCIPHERMENT,
385
- KeyUsage::AU_KEY_AGREEMENT, KeyUsage::AU_CRL_SIGN, KeyUsage::AU_DECIPHER_ONLY,
386
- KeyUsage::AU_NON_REPUDIATION, KeyUsage::AU_DATA_ENCIPHERMENT,
387
- KeyUsage::AU_CERTIFICATE_SIGN, KeyUsage::AU_ENCIPHER_ONLY ]
388
- @extension_value = @allowed_uses.join( ", " )
389
- end
458
+ it "should raise an ArgumentError for #wrap_openssl_extensions" do
459
+ expect {
460
+ R509::Cert::Extensions.wrap_openssl_extensions( @openssl_extensions )
461
+ }.to raise_error(ArgumentError)
462
+ end
463
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
464
+ end
465
+
466
+ context "with multiple extensions of an unimplemented type" do
467
+ before :each do
468
+ @wrappable_extensions = []
469
+ ef = OpenSSL::X509::ExtensionFactory.new
470
+ @wrappable_extensions << ef.create_extension( "basicConstraints", "CA:TRUE,pathlen:0" )
390
471
 
391
- it_should_behave_like "a correct R509 KeyUsage object"
472
+ @unknown_extensions = []
473
+ @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www.test.local" )
474
+ @unknown_extensions << OpenSSL::X509::Extension.new( "issuerAltName", "DNS:www2.test.local" )
475
+
476
+ @openssl_extensions = @wrappable_extensions + @unknown_extensions
392
477
  end
478
+
479
+ it_should_behave_like "a correctly implemented wrap_openssl_extensions"
480
+ it_should_behave_like "a correctly implemented get_unknown_extensions"
481
+ end
482
+ end
483
+ end
484
+
485
+ context "BasicConstraints" do
486
+ context "with constraints for a CA certificate" do
487
+ before :all do
488
+ @extension_value = "CA:TRUE,pathlen:3"
489
+ @is_ca = true
490
+ @pathlen = 3
491
+ @allows_sub_ca = true
492
+ end
493
+
494
+ it_should_behave_like "a correct R509 BasicConstraints object", false
495
+ it_should_behave_like "a correct R509 BasicConstraints object", true
393
496
  end
394
497
 
395
- context "ExtendedKeyUsage" do
396
- context "with one allowed use" do
397
- before :all do
398
- @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH ]
399
- @extension_value = @allowed_uses.join( ", " )
400
- end
498
+ context "with constraints for a sub-CA certificate" do
499
+ before :all do
500
+ @extension_value = "CA:TRUE,pathlen:0"
501
+ @is_ca = true
502
+ @pathlen = 0
503
+ @allows_sub_ca = false
504
+ end
401
505
 
402
- it_should_behave_like "a correct R509 ExtendedKeyUsage object"
403
- end
506
+ it_should_behave_like "a correct R509 BasicConstraints object", false
507
+ it_should_behave_like "a correct R509 BasicConstraints object", true
508
+ end
404
509
 
405
- context "with some allowed uses" do
406
- before :all do
407
- # this spec and the one below alternate the uses
408
- @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH, ExtendedKeyUsage::AU_CODE_SIGNING ]
409
- @extension_value = @allowed_uses.join( ", " )
410
- end
510
+ context "with constraints for a non-CA certificate" do
511
+ before :all do
512
+ @extension_value = "CA:FALSE"
513
+ @is_ca = false
514
+ @pathlen = nil
515
+ @allows_sub_ca = false
516
+ end
411
517
 
412
- it_should_behave_like "a correct R509 ExtendedKeyUsage object"
413
- end
518
+ it_should_behave_like "a correct R509 BasicConstraints object", false
519
+ it_should_behave_like "a correct R509 BasicConstraints object", true
520
+ end
521
+ end
414
522
 
415
- context "with some different allowed uses" do
416
- before :all do
417
- @allowed_uses = [ ExtendedKeyUsage::AU_WEB_CLIENT_AUTH, ExtendedKeyUsage::AU_EMAIL_PROTECTION ]
418
- @extension_value = @allowed_uses.join( ", " )
419
- end
523
+ context "KeyUsage" do
524
+ context "with one allowed use" do
525
+ before :all do
526
+ @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE ]
527
+ @extension_value = @allowed_uses.join( ", " )
528
+ end
420
529
 
421
- it_should_behave_like "a correct R509 ExtendedKeyUsage object"
422
- end
530
+ it_should_behave_like "a correct R509 KeyUsage object", false
531
+ it_should_behave_like "a correct R509 KeyUsage object", true
532
+ end
423
533
 
424
- context "with all allowed uses" do
425
- before :all do
426
- @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH, ExtendedKeyUsage::AU_CODE_SIGNING,
427
- ExtendedKeyUsage::AU_WEB_CLIENT_AUTH, ExtendedKeyUsage::AU_EMAIL_PROTECTION ]
428
- @extension_value = @allowed_uses.join( ", " )
429
- end
534
+ context "with some allowed uses" do
535
+ before :all do
536
+ # this spec and the one below alternate the uses
537
+ @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE, KeyUsage::AU_KEY_ENCIPHERMENT, KeyUsage::AU_KEY_AGREEMENT, KeyUsage::AU_CRL_SIGN, KeyUsage::AU_DECIPHER_ONLY ]
538
+ @extension_value = @allowed_uses.join( ", " )
539
+ end
430
540
 
431
- it_should_behave_like "a correct R509 ExtendedKeyUsage object"
432
- end
541
+ it_should_behave_like "a correct R509 KeyUsage object", false
542
+ it_should_behave_like "a correct R509 KeyUsage object", true
433
543
  end
434
544
 
435
- context "SubjectKeyIdentifier" do
436
- before :all do
437
- @extension_value = "00:11:22:33:44:55:66:77:88:99:00:AA:BB:CC:DD:EE:FF:00:11:22"
438
- @key = @extension_value
439
- end
545
+ context "with some different allowed uses" do
546
+ before :all do
547
+ @allowed_uses = [ KeyUsage::AU_NON_REPUDIATION, KeyUsage::AU_DATA_ENCIPHERMENT, KeyUsage::AU_KEY_CERT_SIGN, KeyUsage::AU_ENCIPHER_ONLY ]
548
+ @extension_value = @allowed_uses.join( ", " )
549
+ end
440
550
 
441
- it_should_behave_like "a correct R509 SubjectKeyIdentifier object"
551
+ it_should_behave_like "a correct R509 KeyUsage object", false
552
+ it_should_behave_like "a correct R509 KeyUsage object", true
442
553
  end
443
554
 
444
- context "AuthorityKeyIdentifier" do
445
- before :all do
446
- @extension_value = "keyid:always"
447
- end
555
+ context "with all allowed uses" do
556
+ before :all do
557
+ @allowed_uses = [ KeyUsage::AU_DIGITAL_SIGNATURE, KeyUsage::AU_NON_REPUDIATION,
558
+ KeyUsage::AU_KEY_ENCIPHERMENT, KeyUsage::AU_DATA_ENCIPHERMENT,
559
+ KeyUsage::AU_KEY_AGREEMENT, KeyUsage::AU_KEY_CERT_SIGN,
560
+ KeyUsage::AU_CRL_SIGN, KeyUsage::AU_ENCIPHER_ONLY,
561
+ KeyUsage::AU_DECIPHER_ONLY ]
562
+ @extension_value = @allowed_uses.join( ", " )
563
+ end
448
564
 
449
- it_should_behave_like "a correct R509 AuthorityKeyIdentifier object"
565
+ it_should_behave_like "a correct R509 KeyUsage object", false
566
+ it_should_behave_like "a correct R509 KeyUsage object", true
450
567
  end
568
+ end
451
569
 
452
- context "SubjectAlternativeName" do
453
- context "with a DNS alternative name only" do
454
- before :all do
455
- @dns_names = ["www.test.local"]
456
- @ip_addresses = []
457
- @uris = []
458
- @extension_value = "DNS:#{@dns_names.join(",DNS:")}"
459
- end
570
+ context "ExtendedKeyUsage" do
571
+ context "with one allowed use" do
572
+ before :all do
573
+ @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH ]
574
+ @extension_value = @allowed_uses.join( ", " )
575
+ end
460
576
 
461
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
462
- end
577
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", false
578
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", true
579
+ end
463
580
 
464
- context "with multiple DNS alternative names only" do
465
- before :all do
466
- @dns_names = ["www.test.local", "www2.test.local"]
467
- @ip_addresses = []
468
- @uris = []
469
- @extension_value = "DNS:#{@dns_names.join(",DNS:")}"
470
- end
581
+ context "with some allowed uses" do
582
+ before :all do
583
+ # this spec and the one below alternate the uses
584
+ @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH, ExtendedKeyUsage::AU_CODE_SIGNING ]
585
+ @extension_value = @allowed_uses.join( ", " )
586
+ end
471
587
 
472
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
473
- end
588
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", false
589
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", true
590
+ end
474
591
 
475
- context "with an IP address alternative name only" do
476
- before :all do
477
- @dns_names = []
478
- @ip_addresses = ["10.1.2.3"]
479
- @uris = []
480
- @extension_value = "IP:#{@ip_addresses.join(",IP:")}"
481
- end
592
+ context "with some different allowed uses" do
593
+ before :all do
594
+ @allowed_uses = [ ExtendedKeyUsage::AU_WEB_CLIENT_AUTH, ExtendedKeyUsage::AU_EMAIL_PROTECTION ]
595
+ @extension_value = @allowed_uses.join( ", " )
596
+ end
482
597
 
483
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
484
- end
598
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", false
599
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", true
600
+ end
485
601
 
486
- context "with multiple IP address alternative names only" do
487
- before :all do
488
- @dns_names = []
489
- @ip_addresses = ["10.1.2.3", "10.1.2.4"]
490
- @uris = []
491
- @extension_value = "IP:#{@ip_addresses.join(",IP:")}"
492
- end
602
+ context "with all allowed uses" do
603
+ before :all do
604
+ @allowed_uses = [ ExtendedKeyUsage::AU_WEB_SERVER_AUTH, ExtendedKeyUsage::AU_CODE_SIGNING,
605
+ ExtendedKeyUsage::AU_WEB_CLIENT_AUTH, ExtendedKeyUsage::AU_EMAIL_PROTECTION,
606
+ ExtendedKeyUsage::AU_TIME_STAMPING, ExtendedKeyUsage::AU_OCSP_SIGNING,
607
+ ExtendedKeyUsage::AU_ANY_EXTENDED_KEY_USAGE]
608
+ @extension_value = @allowed_uses.join( ", " )
609
+ end
493
610
 
494
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
495
- end
611
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", false
612
+ it_should_behave_like "a correct R509 ExtendedKeyUsage object", true
613
+ end
614
+ end
496
615
 
497
- context "with a URI alternative name only" do
498
- before :all do
499
- @dns_names = []
500
- @ip_addresses = []
501
- @uris = ["http://www.test.local"]
502
- @extension_value = "URI:#{@uris.join(",URI:")}"
503
- end
616
+ context "SubjectKeyIdentifier" do
617
+ before :all do
618
+ @extension_value = "00:11:22:33:44:55:66:77:88:99:00:AA:BB:CC:DD:EE:FF:00:11:22"
619
+ @key = @extension_value
620
+ end
504
621
 
505
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
506
- end
622
+ it_should_behave_like "a correct R509 SubjectKeyIdentifier object"
623
+ end
507
624
 
508
- context "with multiple URI alternative names only" do
509
- before :all do
510
- @dns_names = []
511
- @ip_addresses = []
512
- @uris = ["http://www.test.local","http://www2.test.local"]
513
- @extension_value = "URI:#{@uris.join(",URI:")}"
514
- end
625
+ context "AuthorityKeyIdentifier" do
626
+ before :all do
627
+ @extension_value = "keyid:always,issuer:always"
628
+ end
515
629
 
516
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
517
- end
630
+ it_should_behave_like "a correct R509 AuthorityKeyIdentifier object"
631
+ end
518
632
 
519
- context "with multiple different alternative names" do
520
- before :all do
521
- @dns_names = ["www.test.local"]
522
- @ip_addresses = ["10.1.2.3"]
523
- @uris = ["http://www.test.local"]
524
- @extension_value = "DNS:#{@dns_names.join(",DNS:")},IP:#{@ip_addresses.join(",IP:")},URI:#{@uris.join(",URI:")}"
525
- end
633
+ context "SubjectAlternativeName" do
634
+ context "with an unimplemented GeneralName type" do
635
+ it "errors as expected" do
636
+ ef = OpenSSL::X509::ExtensionFactory.new
637
+ ext = ef.create_extension("subjectAltName","otherName:1.2.3.4;IA5STRING:Hello World")
638
+ expect { R509::Cert::Extensions::SubjectAlternativeName.new ext }.to raise_error(R509::R509Error, 'Unimplemented GeneralName tag: 0. At this time R509 does not support GeneralName types other than rfc822Name, dNSName, uniformResourceIdentifier, iPAddress, and directoryName')
639
+ end
640
+ end
641
+ context "with a DNS alternative name only" do
642
+ before :all do
643
+ @dns_names = ["www.test.local"]
644
+ @ip_addresses = []
645
+ @uris = []
646
+ @rfc_822_names = []
647
+ @directory_names = []
648
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
649
+ gns = R509::ASN1.general_name_parser(total)
650
+ serialized = gns.serialize_names
651
+ @conf = serialized[:conf]
652
+ @extension_value = serialized[:extension_string]
653
+ end
526
654
 
527
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
528
- end
655
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
656
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
657
+ end
529
658
 
530
- context "with multiple different alternative names with trailing newlines" do
531
- before :all do
532
- @dns_names = ["www.test.local"]
533
- @ip_addresses = ["10.1.2.3"]
534
- @uris = ["http://www.test.local"]
535
- @extension_value = "DNS:#{@dns_names.join("\n,DNS:")}\n,IP:#{@ip_addresses.join("\n,IP:")}\n,URI:#{@uris.join("\n,URI:")}\n"
536
- end
659
+ context "with multiple DNS alternative names only" do
660
+ before :all do
661
+ @dns_names = ["www.test.local", "www2.test.local"]
662
+ @ip_addresses = []
663
+ @uris = []
664
+ @rfc_822_names = []
665
+ @directory_names = []
666
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
667
+ gns = R509::ASN1.general_name_parser(total)
668
+ serialized = gns.serialize_names
669
+ @conf = serialized[:conf]
670
+ @extension_value = serialized[:extension_string]
671
+ end
537
672
 
538
- it_should_behave_like "a correct R509 SubjectAlternativeName object"
539
- end
673
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
674
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
540
675
  end
541
- context "AuthorityInfoAccess" do
542
- context "with a CA Issuers URI only" do
543
- before :all do
544
- @ca_issuers_uris = ["http://www.test.local/ca.cert"]
545
- @ocsp_uris = []
546
- @extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join(",URI:")}"
547
- end
548
676
 
549
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
550
- end
677
+ context "with an IP address alternative name only" do
678
+ before :all do
679
+ @dns_names = []
680
+ @ip_addresses = ["203.1.2.3"]
681
+ @rfc_822_names = []
682
+ @uris = []
683
+ @directory_names = []
684
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
685
+ gns = R509::ASN1.general_name_parser(total)
686
+ serialized = gns.serialize_names
687
+ @conf = serialized[:conf]
688
+ @extension_value = serialized[:extension_string]
689
+ end
551
690
 
552
- context "with multiple CA Issuers URIs only" do
553
- before :all do
554
- @ca_issuers_uris = ["http://www.test.local/ca.cert", "http://www.test.local/subca.cert"]
555
- @ocsp_uris = []
556
- @extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join(",CA Issuers - URI:")}"
557
- end
691
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
692
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
693
+ end
558
694
 
559
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
560
- end
695
+ context "with multiple IP address alternative names only" do
696
+ before :all do
697
+ @dns_names = []
698
+ @ip_addresses = ["10.1.2.3", "10.1.2.4"]
699
+ @uris = []
700
+ @rfc_822_names = []
701
+ @directory_names = []
702
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
703
+ gns = R509::ASN1.general_name_parser(total)
704
+ serialized = gns.serialize_names
705
+ @conf = serialized[:conf]
706
+ @extension_value = serialized[:extension_string]
707
+ end
561
708
 
562
- context "with an OCSP URI only" do
563
- before :all do
564
- @ca_issuers_uris = []
565
- @ocsp_uris = ["http://www.test.local"]
566
- @extension_value = "OCSP - URI:#{@ocsp_uris.join(",URI:")}"
567
- end
709
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
710
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
711
+ end
568
712
 
569
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
570
- end
713
+ context "with an rfc822Name alternative name only" do
714
+ before :all do
715
+ @dns_names = []
716
+ @ip_addresses = []
717
+ @rfc_822_names = ["some@guy.com"]
718
+ @uris = []
719
+ @directory_names = []
720
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
721
+ gns = R509::ASN1.general_name_parser(total)
722
+ serialized = gns.serialize_names
723
+ @conf = serialized[:conf]
724
+ @extension_value = serialized[:extension_string]
725
+ end
571
726
 
572
- context "with multiple OCSP URIs only" do
573
- before :all do
574
- @ca_issuers_uris = []
575
- @ocsp_uris = ["http://www.test.local", "http://www2.test.local"]
576
- @extension_value = "OCSP - URI:#{@ocsp_uris.join(",OCSP - URI:")}"
577
- end
727
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
728
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
729
+ end
578
730
 
579
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
580
- end
731
+ context "with multiple rfc822Name alternative names only" do
732
+ before :all do
733
+ @dns_names = []
734
+ @ip_addresses = []
735
+ @rfc_822_names = ["some@guy.com","other@guy.com"]
736
+ @uris = []
737
+ @directory_names = []
738
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
739
+ gns = R509::ASN1.general_name_parser(total)
740
+ serialized = gns.serialize_names
741
+ @conf = serialized[:conf]
742
+ @extension_value = serialized[:extension_string]
743
+ end
581
744
 
582
- context "with both a CA Issuers URI and an OCSP URI" do
583
- before :all do
584
- @ca_issuers_uris = ["http://www.test.local/ca.cert"]
585
- @ocsp_uris = ["http://www.test.local"]
586
- @extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join(",CA Issuers - URI:")},OCSP - URI:#{@ocsp_uris.join(",URI:")}"
587
- end
745
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
746
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
747
+ end
588
748
 
589
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
590
- end
749
+ context "with a URI alternative name only" do
750
+ before :all do
751
+ @dns_names = []
752
+ @ip_addresses = []
753
+ @rfc_822_names = []
754
+ @uris = ["http://www.test.local"]
755
+ @directory_names = []
756
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
757
+ gns = R509::ASN1.general_name_parser(total)
758
+ serialized = gns.serialize_names
759
+ @conf = serialized[:conf]
760
+ @extension_value = serialized[:extension_string]
761
+ end
591
762
 
592
- context "with both a CA Issuers URI and an OCSP URI with trailing newlines" do
593
- before :all do
594
- @ca_issuers_uris = ["http://www.test.local/ca.cert"]
595
- @ocsp_uris = ["http://www.test.local"]
596
- @extension_value = "CA Issuers - URI:#{@ca_issuers_uris.join("\n,CA Issuers - URI:")}\n,OCSP - URI:#{@ocsp_uris.join("\n,URI:")}\n"
597
- end
763
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
764
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
765
+ end
598
766
 
599
- it_should_behave_like "a correct R509 AuthorityInfoAccess object"
600
- end
767
+ context "with multiple URI alternative names only" do
768
+ before :all do
769
+ @dns_names = []
770
+ @ip_addresses = []
771
+ @rfc_822_names = []
772
+ @uris = ["http://www.test.local","http://www2.test.local"]
773
+ @directory_names = []
774
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
775
+ gns = R509::ASN1.general_name_parser(total)
776
+ serialized = gns.serialize_names
777
+ @conf = serialized[:conf]
778
+ @extension_value = serialized[:extension_string]
779
+ end
780
+
781
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
782
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
601
783
  end
602
784
 
603
- context "CrlDistributionPoints" do
604
- context "wtih a single CRL URI" do
605
- before :all do
606
- @crl_uris = ["http://www.test.local/ca.crl"]
607
- @extension_value = "URI:#{@crl_uris.join(",URI:")}"
608
- end
785
+ context "with a directoryName alternative name only" do
786
+ before :all do
787
+ @dns_names = []
788
+ @ip_addresses = []
789
+ @rfc_822_names = []
790
+ @uris = []
791
+ @directory_names = [
792
+ [['CN','langui.sh'],['O','org'],['L','locality']]
793
+ ]
794
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
795
+ gns = R509::ASN1.general_name_parser(total)
796
+ serialized = gns.serialize_names
797
+ @conf = serialized[:conf]
798
+ @extension_value = serialized[:extension_string]
799
+ end
609
800
 
610
- it_should_behave_like "a correct R509 CrlDistributionPoints object"
611
- end
801
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
802
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
803
+ end
804
+
805
+ context "with multiple directoryName alternative names only" do
806
+ before :all do
807
+ @dns_names = []
808
+ @ip_addresses = []
809
+ @rfc_822_names = []
810
+ @uris = []
811
+ @directory_names = [
812
+ [['CN','langui.sh'],['O','org'],['L','locality']],
813
+ [['CN','otherdomain.com'],['O','org-like']]
814
+ ]
815
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
816
+ gns = R509::ASN1.general_name_parser(total)
817
+ serialized = gns.serialize_names
818
+ @conf = serialized[:conf]
819
+ @extension_value = serialized[:extension_string]
820
+ end
612
821
 
613
- context "wtih multiple CRL URIs" do
614
- before :all do
615
- @crl_uris = ["http://www.test.local/ca.crl", "http://www.test.local/subca.crl"]
616
- @extension_value = "URI:#{@crl_uris.join(",URI:")}"
617
- end
822
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
823
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
824
+ end
825
+
826
+ context "with multiple different alternative names" do
827
+ before :all do
828
+ @dns_names = ["www.test.local"]
829
+ @ip_addresses = ["10.1.2.3"]
830
+ @rfc_822_names = ["myemail@email.com"]
831
+ @uris = ["http://www.test.local"]
832
+ @directory_names = [
833
+ [['CN','langui.sh'],['O','org'],['L','locality']]
834
+ ]
835
+ total = [@dns_names,@ip_addresses,@uris,@rfc_822_names,@directory_names].flatten(1)
836
+ gns = R509::ASN1.general_name_parser(total)
837
+ serialized = gns.serialize_names
838
+ @conf = serialized[:conf]
839
+ @extension_value = serialized[:extension_string]
840
+ end
841
+
842
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", false
843
+ it_should_behave_like "a correct R509 SubjectAlternativeName object", true
844
+ end
845
+ end
846
+ context "AuthorityInfoAccess" do
847
+ context "with a CA Issuers URI only" do
848
+ before :all do
849
+ @ca_issuers_uris = ["http://www.test.local/ca.cert"]
850
+ @ocsp_uris = []
851
+ @extension_value = "caIssuers;URI:#{@ca_issuers_uris.join(",caIssuers;URI:")}"
852
+ end
853
+
854
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", false
855
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", true
856
+ end
857
+
858
+ context "with multiple CA Issuers URIs only" do
859
+ before :all do
860
+ @ca_issuers_uris = ["http://www.test.local/ca.cert", "http://www.test.local/subca.cert"]
861
+ @ocsp_uris = []
862
+ @extension_value = "caIssuers;URI:#{@ca_issuers_uris.join(",caIssuers;URI:")}"
863
+ end
864
+
865
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", false
866
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", true
867
+ end
868
+
869
+ context "with an OCSP URI only" do
870
+ before :all do
871
+ @ca_issuers_uris = []
872
+ @ocsp_uris = ["http://www.test.local"]
873
+ @extension_value = "OCSP;URI:#{@ocsp_uris.join(",OCSP;URI:")}"
874
+ end
875
+
876
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", false
877
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", true
878
+ end
879
+
880
+ context "with multiple OCSP URIs only" do
881
+ before :all do
882
+ @ca_issuers_uris = []
883
+ @ocsp_uris = ["http://www.test.local", "http://www2.test.local"]
884
+ @extension_value = "OCSP;URI:#{@ocsp_uris.join(",OCSP;URI:")}"
885
+ end
886
+
887
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", false
888
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", true
889
+ end
890
+
891
+ context "with both a CA Issuers URI and an OCSP URI" do
892
+ before :all do
893
+ @ca_issuers_uris = ["http://www.test.local/ca.cert"]
894
+ @ocsp_uris = ["http://www.test.local"]
895
+ @extension_value = "caIssuers;URI:#{@ca_issuers_uris.join(",caIssuers;URI:")},OCSP;URI:#{@ocsp_uris.join(",OCSP;URI:")}"
896
+ end
897
+
898
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", false
899
+ it_should_behave_like "a correct R509 AuthorityInfoAccess object", true
900
+ end
901
+ end
902
+
903
+ context "CRLDistributionPoints" do
904
+ context "with a single CRL URI" do
905
+ before :all do
906
+ @crl_uris = ["http://www.test.local/ca.crl"]
907
+ @extension_value = "URI:#{@crl_uris.join(",URI:")}"
908
+ end
909
+
910
+ it_should_behave_like "a correct R509 CRLDistributionPoints object", false
911
+ it_should_behave_like "a correct R509 CRLDistributionPoints object", true
912
+ end
913
+
914
+ context "with multiple CRL URIs" do
915
+ before :all do
916
+ @crl_uris = ["http://www.test.local/ca.crl", "http://www.test.local/subca.crl"]
917
+ @extension_value = "URI:#{@crl_uris.join(",URI:")}"
918
+ end
919
+
920
+ it_should_behave_like "a correct R509 CRLDistributionPoints object", false
921
+ it_should_behave_like "a correct R509 CRLDistributionPoints object", true
922
+ end
923
+ end
924
+
925
+ context "OCSPNoCheck" do
926
+ it_should_behave_like "a correct R509 OCSPNoCheck object", false
927
+ it_should_behave_like "a correct R509 OCSPNoCheck object", true
928
+ end
929
+
930
+ context "CertificatePolicies" do
931
+ before :all do
932
+ @policy_data = "0\x81\x90\x06\x03U\x1D \x04\x81\x880\x81\x850\x81\x82\x06\v`\x86H\x01\xE09\x01\x02\x03\x04\x010s0\"\x06\b+\x06\x01\x05\x05\a\x02\x01\x16\x16http://example.com/cps0 \x06\b+\x06\x01\x05\x05\a\x02\x01\x16\x14http://other.com/cps0+\x06\b+\x06\x01\x05\x05\a\x02\x020\x1F0\x16\x16\x06my org0\f\x02\x01\x01\x02\x01\x02\x02\x01\x03\x02\x01\x04\x1A\x05thing"
933
+ end
934
+
935
+ it_should_behave_like "a correct R509 CertificatePolicies object"
936
+ end
937
+
938
+ context "InhibitAnyPolicy" do
939
+ before :all do
940
+ @skip_certs = 3
941
+ end
942
+
943
+ it_should_behave_like "a correct R509 InhibitAnyPolicy object", false
944
+ it_should_behave_like "a correct R509 InhibitAnyPolicy object", true
945
+ end
946
+
947
+ context "PolicyConstraints" do
948
+ context "with just require" do
949
+ before :all do
950
+ @require_explicit_policy = 2
951
+ @inhibit_policy_mapping = nil
952
+ @extension_value = "requireExplicitPolicy:#{@require_explicit_policy}"
953
+ end
954
+ it_should_behave_like "a correct R509 PolicyConstraints object", false
955
+ it_should_behave_like "a correct R509 PolicyConstraints object", true
956
+ end
957
+ context "with just inhibit" do
958
+ before :all do
959
+ @require_explicit_policy = nil
960
+ @inhibit_policy_mapping = 3
961
+ @extension_value = "inhibitPolicyMapping:#{@inhibit_policy_mapping}"
962
+ end
963
+ it_should_behave_like "a correct R509 PolicyConstraints object", false
964
+ it_should_behave_like "a correct R509 PolicyConstraints object", true
965
+ end
966
+ context "with both require and inhibit" do
967
+ before :all do
968
+ @require_explicit_policy = 2
969
+ @inhibit_policy_mapping = 3
970
+ @extension_value = "requireExplicitPolicy:#{@require_explicit_policy},inhibitPolicyMapping:#{@inhibit_policy_mapping}"
971
+ end
972
+ it_should_behave_like "a correct R509 PolicyConstraints object", false
973
+ it_should_behave_like "a correct R509 PolicyConstraints object", true
974
+ end
618
975
 
619
- it_should_behave_like "a correct R509 CrlDistributionPoints object"
976
+ end
977
+
978
+ context "NameConstraints" do
979
+ context "with one permitted name" do
980
+ before :all do
981
+ @excluded_names = []
982
+ @permitted_names = [{:tag => 2, :value => ".whatever.com"}]
983
+ gns = R509::ASN1::GeneralNames.new
984
+ @permitted_names.each do |name|
985
+ gns.add_item(name)
620
986
  end
987
+ @conf = []
988
+ permitted = gns.names.map { |name|
989
+ serialized = name.serialize_name
990
+ @conf << serialized[:conf]
991
+ "permitted;" + serialized[:extension_string]
992
+ }.join(",")
993
+ @extension_value = permitted
994
+ @conf = @conf.join("\n")
995
+ end
621
996
 
622
- context "wtih multiple CRL URIs and trailing newlines" do
623
- before :all do
624
- @crl_uris = ["http://www.test.local/ca.crl", "http://www.test.local/subca.crl"]
625
- @extension_value = "URI:#{@crl_uris.join("\n,URI:")}\n"
626
- end
997
+ it_should_behave_like "a correct R509 NameConstraints object", false
998
+ it_should_behave_like "a correct R509 NameConstraints object", true
999
+ end
1000
+ context "with multiple permitted names" do
1001
+ before :all do
1002
+ @excluded_names = []
1003
+ @permitted_names = [{:tag => 2, :value => ".whatever.com"}, {:tag => 1, :value => "user@emaildomain.com" } ]
1004
+ gns = R509::ASN1::GeneralNames.new
1005
+ @permitted_names.each do |name|
1006
+ gns.add_item(name)
1007
+ end
1008
+ @conf = []
1009
+ permitted = gns.names.map { |name|
1010
+ serialized = name.serialize_name
1011
+ @conf << serialized[:conf]
1012
+ "permitted;" + serialized[:extension_string]
1013
+ }.join(",")
1014
+ @extension_value = permitted
1015
+ @conf = @conf.join("\n")
1016
+ end
1017
+
1018
+ it_should_behave_like "a correct R509 NameConstraints object", false
1019
+ it_should_behave_like "a correct R509 NameConstraints object", true
1020
+ end
1021
+ context "with one excluded name" do
1022
+ before :all do
1023
+ @permitted_names = []
1024
+ @excluded_names = [{:tag => 7, :value => "127.0.0.1/255.255.255.255"}]
1025
+ egns = R509::ASN1::GeneralNames.new
1026
+ @excluded_names.each do |name|
1027
+ egns.add_item(name)
1028
+ end
1029
+ @conf = []
1030
+ excluded = egns.names.map { |name|
1031
+ serialized = name.serialize_name
1032
+ @conf << serialized[:conf]
1033
+ "excluded;" + serialized[:extension_string]
1034
+ }.join(",")
1035
+ @extension_value = excluded
1036
+ @conf = @conf.join("\n")
1037
+ end
627
1038
 
628
- it_should_behave_like "a correct R509 CrlDistributionPoints object"
1039
+ it_should_behave_like "a correct R509 NameConstraints object", false
1040
+ it_should_behave_like "a correct R509 NameConstraints object", true
1041
+ end
1042
+ context "with multiple excluded names" do
1043
+ before :all do
1044
+ @permitted_names = []
1045
+ @excluded_names = [{:tag => 7, :value => "127.0.0.1/255.255.255.255"}, {:tag => 1, :value => "emaildomain.com" } ]
1046
+ @permitted_names = []
1047
+ egns = R509::ASN1::GeneralNames.new
1048
+ @excluded_names.each do |name|
1049
+ egns.add_item(name)
629
1050
  end
1051
+ @conf = []
1052
+ excluded = egns.names.map { |name|
1053
+ serialized = name.serialize_name
1054
+ @conf << serialized[:conf]
1055
+ "excluded;" + serialized[:extension_string]
1056
+ }.join(",")
1057
+ @extension_value = excluded
1058
+ @conf = @conf.join("\n")
1059
+ end
1060
+
1061
+ it_should_behave_like "a correct R509 NameConstraints object", false
1062
+ it_should_behave_like "a correct R509 NameConstraints object", true
630
1063
  end
1064
+ context "with both permitted and excluded names" do
1065
+ before :all do
1066
+ @excluded_names = [{:tag => 7, :value => "127.0.0.1/255.255.255.255"}, {:tag => 1, :value => "emaildomain.com" } ]
1067
+ @permitted_names = [{:tag => 2, :value => ".whatever.com"}, {:tag => 1, :value => "user@emaildomain.com"} ]
1068
+ gns = R509::ASN1::GeneralNames.new
1069
+ @permitted_names.each do |name|
1070
+ gns.add_item(name)
1071
+ end
1072
+ @conf = []
1073
+ permitted = gns.names.map { |name|
1074
+ serialized = name.serialize_name
1075
+ @conf << serialized[:conf]
1076
+ "permitted;" + serialized[:extension_string]
1077
+ }.join(",")
1078
+ egns = R509::ASN1::GeneralNames.new
1079
+ @excluded_names.each do |name|
1080
+ egns.add_item(name)
1081
+ end
1082
+ excluded = egns.names.map { |name|
1083
+ serialized = name.serialize_name
1084
+ @conf << serialized[:conf]
1085
+ "excluded;" + serialized[:extension_string]
1086
+ }.join(",")
1087
+ @extension_value = permitted + "," + excluded
1088
+ @conf = @conf.join("\n")
1089
+ end
631
1090
 
1091
+ it_should_behave_like "a correct R509 NameConstraints object", false
1092
+ it_should_behave_like "a correct R509 NameConstraints object", true
1093
+ end
1094
+ end
632
1095
  end