r509 0.9.2 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (177) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -0
  4. data/CONTRIBUTING.mdown +21 -0
  5. data/LICENSE +13 -0
  6. data/README.mdown +548 -0
  7. data/Rakefile +5 -0
  8. data/bin/r509 +16 -17
  9. data/doc/R509.html +42 -26
  10. data/doc/R509/ASN1.html +22 -16
  11. data/doc/R509/ASN1/GeneralName.html +180 -173
  12. data/doc/R509/ASN1/GeneralNames.html +390 -62
  13. data/doc/R509/CRL.html +9 -7
  14. data/doc/R509/CRL/Administrator.html +208 -623
  15. data/doc/R509/CRL/FileReaderWriter.html +856 -0
  16. data/doc/R509/CRL/ReaderWriter.html +524 -0
  17. data/doc/R509/CRL/SignedList.html +29 -42
  18. data/doc/R509/CSR.html +248 -333
  19. data/doc/R509/Cert.html +364 -491
  20. data/doc/R509/Cert/Extensions.html +134 -43
  21. data/doc/R509/Cert/Extensions/AuthorityInfoAccess.html +335 -65
  22. data/doc/R509/Cert/Extensions/AuthorityKeyIdentifier.html +201 -102
  23. data/doc/R509/Cert/Extensions/BasicConstraints.html +297 -68
  24. data/doc/R509/Cert/Extensions/CRLDistributionPoints.html +690 -77
  25. data/doc/R509/Cert/Extensions/CertificatePolicies.html +293 -43
  26. data/doc/R509/Cert/Extensions/ExtendedKeyUsage.html +321 -173
  27. data/doc/R509/Cert/Extensions/GeneralNamesMixin.html +656 -0
  28. data/doc/R509/Cert/Extensions/InhibitAnyPolicy.html +270 -42
  29. data/doc/R509/Cert/Extensions/KeyUsage.html +334 -184
  30. data/doc/R509/Cert/Extensions/NameConstraints.html +363 -93
  31. data/doc/R509/{ASN1 → Cert/Extensions}/NoticeReference.html +209 -48
  32. data/doc/R509/Cert/Extensions/OCSPNoCheck.html +244 -17
  33. data/doc/R509/Cert/Extensions/PolicyConstraints.html +322 -71
  34. data/doc/R509/{ASN1 → Cert/Extensions}/PolicyInformation.html +204 -43
  35. data/doc/R509/{ASN1 → Cert/Extensions}/PolicyQualifiers.html +205 -48
  36. data/doc/R509/Cert/Extensions/SubjectAlternativeName.html +348 -143
  37. data/doc/R509/Cert/Extensions/SubjectKeyIdentifier.html +165 -13
  38. data/doc/R509/{ASN1 → Cert/Extensions}/UserNotice.html +204 -43
  39. data/doc/R509/Cert/Extensions/ValidationMixin.html +120 -0
  40. data/doc/R509/CertificateAuthority.html +9 -7
  41. data/doc/R509/CertificateAuthority/OptionsBuilder.html +475 -0
  42. data/doc/R509/CertificateAuthority/Signer.html +149 -198
  43. data/doc/R509/Config.html +10 -8
  44. data/doc/R509/Config/CAConfig.html +708 -625
  45. data/doc/R509/Config/CAConfigPool.html +179 -31
  46. data/doc/R509/Config/CertProfile.html +1544 -0
  47. data/doc/R509/Config/SubjectItemPolicy.html +437 -99
  48. data/doc/R509/Engine.html +14 -28
  49. data/doc/R509/Helpers.html +1014 -0
  50. data/doc/R509/MessageDigest.html +73 -25
  51. data/doc/R509/NameSanitizer.html +39 -39
  52. data/doc/R509/OCSP.html +5 -5
  53. data/doc/R509/OCSP/Request.html +5 -5
  54. data/doc/R509/OCSP/Request/Nonce.html +5 -5
  55. data/doc/R509/OCSP/Response.html +7 -7
  56. data/doc/R509/OIDMapper.html +121 -6
  57. data/doc/R509/PrivateKey.html +226 -227
  58. data/doc/R509/R509Error.html +5 -5
  59. data/doc/R509/SPKI.html +244 -342
  60. data/doc/R509/Subject.html +241 -70
  61. data/doc/R509/Validity.html +5 -5
  62. data/doc/R509/Validity/Checker.html +5 -5
  63. data/doc/R509/Validity/DefaultChecker.html +5 -9
  64. data/doc/R509/Validity/DefaultWriter.html +5 -9
  65. data/doc/R509/Validity/Status.html +5 -5
  66. data/doc/R509/Validity/Writer.html +5 -5
  67. data/doc/_index.html +92 -30
  68. data/doc/class_list.html +2 -2
  69. data/doc/file.CONTRIBUTING.html +96 -0
  70. data/doc/file.LICENSE.html +87 -0
  71. data/doc/file.README.html +279 -389
  72. data/doc/file.YAML.html +243 -0
  73. data/doc/file.r509.html +298 -105
  74. data/doc/file_list.html +11 -2
  75. data/doc/frames.html +1 -1
  76. data/doc/index.html +279 -389
  77. data/doc/js/full_list.js +6 -1
  78. data/doc/method_list.html +869 -1139
  79. data/doc/top-level-namespace.html +103 -5
  80. data/lib/r509.rb +7 -2
  81. data/lib/r509/asn1.rb +97 -135
  82. data/lib/r509/cert.rb +17 -106
  83. data/lib/r509/cert/extensions.rb +13 -676
  84. data/lib/r509/cert/extensions/authority_info_access.rb +128 -0
  85. data/lib/r509/cert/extensions/authority_key_identifier.rb +100 -0
  86. data/lib/r509/cert/extensions/base.rb +142 -0
  87. data/lib/r509/cert/extensions/basic_constraints.rb +119 -0
  88. data/lib/r509/cert/extensions/certificate_policies.rb +262 -0
  89. data/lib/r509/cert/extensions/crl_distribution_points.rb +98 -0
  90. data/lib/r509/cert/extensions/extended_key_usage.rb +189 -0
  91. data/lib/r509/cert/extensions/inhibit_any_policy.rb +70 -0
  92. data/lib/r509/cert/extensions/key_usage.rb +209 -0
  93. data/lib/r509/cert/extensions/name_constraints.rb +179 -0
  94. data/lib/r509/cert/extensions/ocsp_no_check.rb +56 -0
  95. data/lib/r509/cert/extensions/policy_constraints.rb +122 -0
  96. data/lib/r509/cert/extensions/subject_alternative_name.rb +88 -0
  97. data/lib/r509/cert/extensions/subject_key_identifier.rb +56 -0
  98. data/lib/r509/cert/extensions/validation_mixin.rb +42 -0
  99. data/lib/r509/certificate_authority/options_builder.rb +142 -0
  100. data/lib/r509/certificate_authority/signer.rb +189 -0
  101. data/lib/r509/config.rb +3 -600
  102. data/lib/r509/config/ca_config.rb +414 -0
  103. data/lib/r509/config/cert_profile.rb +110 -0
  104. data/lib/r509/config/subject_item_policy.rb +118 -0
  105. data/lib/r509/crl/administrator.rb +169 -0
  106. data/lib/r509/crl/reader_writer.rb +109 -0
  107. data/lib/r509/crl/signed_list.rb +135 -0
  108. data/lib/r509/csr.rb +35 -116
  109. data/lib/r509/engine.rb +21 -11
  110. data/lib/r509/helpers.rb +110 -0
  111. data/lib/r509/io_helpers.rb +18 -13
  112. data/lib/r509/message_digest.rb +13 -3
  113. data/lib/r509/oid_mapper.rb +14 -0
  114. data/lib/r509/private_key.rb +74 -50
  115. data/lib/r509/spki.rb +50 -113
  116. data/lib/r509/subject.rb +24 -2
  117. data/lib/r509/trollop.rb +788 -0
  118. data/lib/r509/version.rb +1 -1
  119. data/r509.yaml +289 -96
  120. data/spec/asn1_spec.rb +171 -98
  121. data/spec/cert/extensions/authority_info_access_spec.rb +247 -0
  122. data/spec/cert/extensions/authority_key_identifier_spec.rb +85 -0
  123. data/spec/cert/extensions/base_spec.rb +172 -0
  124. data/spec/cert/extensions/basic_constraints_spec.rb +185 -0
  125. data/spec/cert/extensions/certificate_policies_spec.rb +288 -0
  126. data/spec/cert/extensions/crl_distribution_points_spec.rb +149 -0
  127. data/spec/cert/extensions/extended_key_usage_spec.rb +174 -0
  128. data/spec/cert/extensions/inhibit_any_policy_spec.rb +92 -0
  129. data/spec/cert/extensions/key_usage_spec.rb +172 -0
  130. data/spec/cert/extensions/name_constraints_spec.rb +335 -0
  131. data/spec/cert/extensions/ocsp_no_check_spec.rb +76 -0
  132. data/spec/cert/extensions/policy_constraints_spec.rb +155 -0
  133. data/spec/cert/extensions/subject_alternative_name_spec.rb +354 -0
  134. data/spec/cert/extensions/subject_key_identifier_spec.rb +64 -0
  135. data/spec/cert_spec.rb +11 -9
  136. data/spec/certificate_authority/options_builder_spec.rb +307 -0
  137. data/spec/certificate_authority/signer_spec.rb +278 -0
  138. data/spec/config/ca_config_spec.rb +405 -0
  139. data/spec/config/cert_profile_spec.rb +88 -0
  140. data/spec/config/subject_item_policy_spec.rb +81 -0
  141. data/spec/crl/administrator_spec.rb +199 -0
  142. data/spec/crl/reader_writer_spec.rb +97 -0
  143. data/spec/crl/signed_list_spec.rb +84 -0
  144. data/spec/csr_spec.rb +43 -36
  145. data/spec/engine_spec.rb +51 -0
  146. data/spec/fixtures.rb +40 -40
  147. data/spec/fixtures/cert1.pem +1 -1
  148. data/spec/fixtures/config_pool_test_minimal.yaml +11 -15
  149. data/spec/fixtures/config_test.yaml +96 -59
  150. data/spec/fixtures/config_test_dsa.yaml +29 -35
  151. data/spec/fixtures/config_test_ec.yaml +29 -35
  152. data/spec/fixtures/config_test_engine_key.yaml +7 -7
  153. data/spec/fixtures/config_test_engine_no_key_name.yaml +6 -6
  154. data/spec/fixtures/config_test_minimal.yaml +3 -5
  155. data/spec/fixtures/config_test_password.yaml +4 -6
  156. data/spec/fixtures/config_test_various.yaml +147 -137
  157. data/spec/fixtures/crl_list_file.txt +1 -1
  158. data/spec/fixtures/test_ca_crl.cer +20 -0
  159. data/spec/fixtures/test_ca_crl.key +28 -0
  160. data/spec/fixtures/test_ca_crl.p12 +0 -0
  161. data/spec/message_digest_spec.rb +6 -0
  162. data/spec/oid_mapper_spec.rb +11 -0
  163. data/spec/private_key_spec.rb +19 -18
  164. data/spec/spec_helper.rb +10 -6
  165. data/spec/spki_spec.rb +38 -19
  166. data/spec/subject_spec.rb +16 -0
  167. metadata +108 -59
  168. metadata.gz.sig +0 -0
  169. data/README.md +0 -638
  170. data/doc/R509/Config/CAProfile.html +0 -1015
  171. data/doc/R509/IOHelpers.html +0 -564
  172. data/lib/r509/certificate_authority.rb +0 -407
  173. data/lib/r509/crl.rb +0 -351
  174. data/spec/cert/extensions_spec.rb +0 -1095
  175. data/spec/certificate_authority_spec.rb +0 -681
  176. data/spec/config_spec.rb +0 -562
  177. data/spec/crl_spec.rb +0 -226
@@ -28,7 +28,7 @@ describe R509::CSR do
28
28
  expect { R509::CSR.new('invalid') }.to raise_error(ArgumentError, 'Must provide a hash of options')
29
29
  end
30
30
  it "key creation defaults to RSA when no type or key is passed" do
31
- csr = R509::CSR.new(:subject => [['CN','testing.rsa']], :bit_strength => 1024)
31
+ csr = R509::CSR.new(:subject => [['CN','testing.rsa']], :bit_length => 1024)
32
32
  csr.rsa?.should == true
33
33
  csr.dsa?.should == false
34
34
  csr.ec?.should == false
@@ -46,19 +46,19 @@ describe R509::CSR do
46
46
  csr.to_pem.should match(/-----BEGIN CERTIFICATE REQUEST-----/)
47
47
  end
48
48
  it "returns true from #has_private_key? when private key is present" do
49
- csr = R509::CSR.new(:bit_strength => 512, :subject => [['CN','private-key-check.com']])
49
+ csr = R509::CSR.new(:bit_length => 512, :subject => [['CN','private-key-check.com']])
50
50
  csr.has_private_key?.should == true
51
51
  end
52
52
  it "returns false from #has_private_key? when private key is not present" do
53
53
  csr = R509::CSR.new(:csr => @csr)
54
54
  csr.has_private_key?.should == false
55
55
  end
56
- it "key creation defaults to 2048 when no bit strength or key is passed" do
56
+ it "key creation defaults to 2048 when no bit length or key is passed" do
57
57
  csr = R509::CSR.new(:subject => [['CN','testing2048.rsa']])
58
- csr.bit_strength.should == 2048
58
+ csr.bit_length.should == 2048
59
59
  end
60
60
  it "creates a CSR when a key is provided" do
61
- csr = R509::CSR.new(:key => @key3, :subject => [['CN','pregenerated.com']], :bit_strength => 1024)
61
+ csr = R509::CSR.new(:key => @key3, :subject => [['CN','pregenerated.com']], :bit_length => 1024)
62
62
  csr.to_pem.should match(/CERTIFICATE REQUEST/)
63
63
  #validate the CSR matches the key
64
64
  csr.req.verify(csr.key.public_key).should == true
@@ -71,10 +71,10 @@ describe R509::CSR do
71
71
  expect { R509::CSR.new(:subject => [['CN','error.com']], :csr => @csr) }.to raise_error(ArgumentError,'You must provide :subject or :csr, not both')
72
72
  end
73
73
  it "raises an exception for not providing valid type when key is nil" do
74
- expect { R509::CSR.new(:subject => [['CN','error.com']], :type => :invalid_symbol) }.to raise_error(ArgumentError,'Must provide :rsa, :dsa, or :ec as type when key is nil')
74
+ expect { R509::CSR.new(:subject => [['CN','error.com']], :type => :invalid_symbol) }.to raise_error(ArgumentError,"Must provide #{R509::PrivateKey::KNOWN_TYPES.join(", ")} as type when key is nil")
75
75
  end
76
76
  it "raises an exception when you don't provide :subject or :csr" do
77
- expect { R509::CSR.new(:bit_strength => 1024) }.to raise_error(ArgumentError,'You must provide :subject or :csr')
77
+ expect { R509::CSR.new(:bit_length => 1024) }.to raise_error(ArgumentError,'You must provide :subject or :csr')
78
78
  end
79
79
  it "raises an exception if you provide a list of domains with an existing CSR" do
80
80
  expect { R509::CSR.new(:csr => @csr, :san_names => ['moredomainsiwanttoadd.com']) }.to raise_error(ArgumentError,'You can\'t add domains to an existing CSR')
@@ -88,7 +88,7 @@ describe R509::CSR do
88
88
  #see http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/PKey/DSA.html
89
89
  end
90
90
  it "changes the message_digest to DSS1 when creating a DSA key" do
91
- csr = R509::CSR.new(:subject => [["CN","dsasigned.com"]], :type => :dsa, :bit_strength => 512)
91
+ csr = R509::CSR.new(:subject => [["CN","dsasigned.com"]], :type => "dsa", :bit_length => 512)
92
92
  csr.message_digest.name.should == 'dss1'
93
93
  csr.signature_algorithm.should == 'dsaWithSHA1'
94
94
  #dss1 is actually the same as SHA1
@@ -100,7 +100,7 @@ describe R509::CSR do
100
100
  csr.verify_signature.should == true
101
101
  end
102
102
  it "signs a CSR properly when creating a DSA key" do
103
- csr = R509::CSR.new(:subject => [["CN","dsasigned.com"]], :type => :dsa, :bit_strength => 512)
103
+ csr = R509::CSR.new(:subject => [["CN","dsasigned.com"]], :type => "dsa", :bit_length => 512)
104
104
  csr.verify_signature.should == true
105
105
  end
106
106
  it "writes to pem" do
@@ -118,11 +118,18 @@ describe R509::CSR do
118
118
  sio.string.should == @csr_der
119
119
  end
120
120
  it "duplicate SAN names should be removed" do
121
- csr = R509::CSR.new( :bit_strength => 512, :subject => [['CN','test2345.com']], :san_names => ["test2.local","test.local","test.local"] )
121
+ csr = R509::CSR.new( :bit_length => 512, :subject => [['CN','test2345.com']], :san_names => ["test2.local","test.local","test.local"] )
122
122
  csr.san.dns_names.should == ["test2.local", "test.local"]
123
123
  end
124
+ it "existing GeneralNames object passed to CSR should be used" do
125
+ gn = R509::ASN1::GeneralNames.new
126
+ gn.create_item(:type => 'dNSName', :value => '127.0.0.1')
127
+ gn.create_item(:type => 'dNSName', :value => '127.0.0.2')
128
+ csr = R509::CSR.new( :bit_length => 512, :subject => [['CN','test2345.com']], :san_names => gn )
129
+ csr.san.dns_names.should == ["127.0.0.1", "127.0.0.2"]
130
+ end
124
131
  it "san is nil when there are no SAN names" do
125
- csr = R509::CSR.new( :subject => [['CN','langui.sh'],['emailAddress','ca@langui.sh']], :bit_strength => 512)
132
+ csr = R509::CSR.new( :subject => [['CN','langui.sh'],['emailAddress','ca@langui.sh']], :bit_length => 512)
126
133
  csr.san.nil?.should == true
127
134
  end
128
135
  context "when initialized" do
@@ -135,15 +142,15 @@ describe R509::CSR do
135
142
  end
136
143
  context "when passing a subject array" do
137
144
  it "generates a matching CSR" do
138
- csr = R509::CSR.new( :subject=> [['CN','langui.sh'],['ST','Illinois'],['L','Chicago'],['C','US'],['emailAddress','ca@langui.sh']], :bit_strength => 1024)
145
+ csr = R509::CSR.new( :subject=> [['CN','langui.sh'],['ST','Illinois'],['L','Chicago'],['C','US'],['emailAddress','ca@langui.sh']], :bit_length => 1024)
139
146
  csr.subject.to_s.should == '/CN=langui.sh/ST=Illinois/L=Chicago/C=US/emailAddress=ca@langui.sh'
140
147
  end
141
148
  it "generates a matching csr when supplying raw oids" do
142
- csr = R509::CSR.new( :subject => [['2.5.4.3','common name'],['2.5.4.15','business category'],['2.5.4.7','locality'],['1.3.6.1.4.1.311.60.2.1.3','jurisdiction oid openssl typically does not know']], :bit_strength => 1024 )
149
+ csr = R509::CSR.new( :subject => [['2.5.4.3','common name'],['2.5.4.15','business category'],['2.5.4.7','locality'],['1.3.6.1.4.1.311.60.2.1.3','jurisdiction oid openssl typically does not know']], :bit_length => 1024 )
143
150
  csr.subject.to_s.should == "/CN=common name/businessCategory=business category/L=locality/jurisdictionOfIncorporationCountryName=jurisdiction oid openssl typically does not know"
144
151
  end
145
152
  it "adds SAN names to a generated CSR" do
146
- csr = R509::CSR.new( :subject => [['CN','test']], :bit_strength => 1024, :san_names => ['1.2.3.4','http://langui.sh','email@address.local','domain.internal','2.3.4.5',[['CN','dirnametest']]])
153
+ csr = R509::CSR.new( :subject => [['CN','test']], :bit_length => 1024, :san_names => ['1.2.3.4','http://langui.sh','email@address.local','domain.internal','2.3.4.5',[['CN','dirnametest']]])
147
154
  csr.san.ip_addresses.should == ['1.2.3.4','2.3.4.5']
148
155
  csr.san.dns_names.should == ['domain.internal']
149
156
  csr.san.uris.should == ['http://langui.sh']
@@ -153,9 +160,9 @@ describe R509::CSR do
153
160
  end
154
161
  end
155
162
  context "when supplying an existing csr" do
156
- it "populates the bit_strength" do
163
+ it "populates the bit_length" do
157
164
  csr = R509::CSR.new({ :csr => @csr })
158
- csr.bit_strength.should == 2048
165
+ csr.bit_length.should == 2048
159
166
  end
160
167
  it "populates the subject" do
161
168
  csr = R509::CSR.new({ :csr => @csr })
@@ -183,11 +190,11 @@ describe R509::CSR do
183
190
  end
184
191
  it "returns RSA key algorithm for RSA CSR" do
185
192
  csr = R509::CSR.new({ :csr => @csr })
186
- csr.key_algorithm.should == :rsa
193
+ csr.key_algorithm.should == "RSA"
187
194
  end
188
195
  it "returns DSA key algorithm for DSA CSR" do
189
196
  csr = R509::CSR.new({ :csr => @csr_dsa })
190
- csr.key_algorithm.should == :dsa
197
+ csr.key_algorithm.should == "DSA"
191
198
  end
192
199
  it "returns the public key" do
193
200
  #this is more complex than it should have to be. diff versions of openssl
@@ -221,32 +228,32 @@ describe R509::CSR do
221
228
  end
222
229
  context "when setting alternate signature algorithms" do
223
230
  it "sets sha1 if you pass an invalid message digest" do
224
- csr = R509::CSR.new(:message_digest => 'sha88', :bit_strength => 512, :subject => [['CN','langui.sh']])
231
+ csr = R509::CSR.new(:message_digest => 'sha88', :bit_length => 512, :subject => [['CN','langui.sh']])
225
232
  csr.message_digest.name.should == 'sha1'
226
233
  csr.signature_algorithm.should == "sha1WithRSAEncryption"
227
234
  end
228
235
  it "sets sha224 properly" do
229
- csr = R509::CSR.new(:message_digest => 'sha224', :bit_strength => 512, :subject => [['CN','sha224-signature-alg.test']])
236
+ csr = R509::CSR.new(:message_digest => 'sha224', :bit_length => 512, :subject => [['CN','sha224-signature-alg.test']])
230
237
  csr.message_digest.name.should == 'sha224'
231
238
  csr.signature_algorithm.should == "sha224WithRSAEncryption"
232
239
  end
233
240
  it "sets sha256 properly" do
234
- csr = R509::CSR.new(:message_digest => 'sha256', :bit_strength => 512, :subject => [['CN','sha256-signature-alg.test']])
241
+ csr = R509::CSR.new(:message_digest => 'sha256', :bit_length => 512, :subject => [['CN','sha256-signature-alg.test']])
235
242
  csr.message_digest.name.should == 'sha256'
236
243
  csr.signature_algorithm.should == "sha256WithRSAEncryption"
237
244
  end
238
245
  it "sets sha384 properly" do
239
- csr = R509::CSR.new(:message_digest => 'sha384', :bit_strength => 768, :subject => [['CN','sha384-signature-alg.test']])
246
+ csr = R509::CSR.new(:message_digest => 'sha384', :bit_length => 768, :subject => [['CN','sha384-signature-alg.test']])
240
247
  csr.message_digest.name.should == 'sha384'
241
248
  csr.signature_algorithm.should == "sha384WithRSAEncryption"
242
249
  end
243
250
  it "sets sha512 properly" do
244
- csr = R509::CSR.new(:message_digest => 'sha512', :bit_strength => 1024, :subject => [['CN','sha512-signature-alg.test']])
251
+ csr = R509::CSR.new(:message_digest => 'sha512', :bit_length => 1024, :subject => [['CN','sha512-signature-alg.test']])
245
252
  csr.message_digest.name.should == 'sha512'
246
253
  csr.signature_algorithm.should == "sha512WithRSAEncryption"
247
254
  end
248
255
  it "sets md5 properly" do
249
- csr = R509::CSR.new(:message_digest => 'md5', :bit_strength => 512, :subject => [['CN','md5-signature-alg.test']])
256
+ csr = R509::CSR.new(:message_digest => 'md5', :bit_length => 512, :subject => [['CN','md5-signature-alg.test']])
250
257
  csr.message_digest.name.should == 'md5'
251
258
  csr.signature_algorithm.should == "md5WithRSAEncryption"
252
259
  end
@@ -257,13 +264,13 @@ describe R509::CSR do
257
264
  csr.ec?.should == false
258
265
  csr.dsa?.should == false
259
266
  end
260
- it "gets RSA bit strength" do
267
+ it "gets RSA bit length" do
261
268
  csr = R509::CSR.new({:csr => @csr})
262
- csr.bit_strength.should == 2048
269
+ csr.bit_length.should == 2048
263
270
  end
264
271
  it "returns an error for curve_name for dsa/rsa CSRs" do
265
272
  csr = R509::CSR.new(:csr => @csr)
266
- expect { csr.curve_name }.to raise_error(R509::R509Error, 'Curve name is only available with EC CSRs')
273
+ expect { csr.curve_name }.to raise_error(R509::R509Error, 'Curve name is only available with EC')
267
274
  end
268
275
  it "checks dsa?" do
269
276
  csr = R509::CSR.new({:csr => @csr_dsa})
@@ -271,9 +278,9 @@ describe R509::CSR do
271
278
  csr.ec?.should == false
272
279
  csr.dsa?.should == true
273
280
  end
274
- it "gets DSA bit strength" do
281
+ it "gets DSA bit length" do
275
282
  csr = R509::CSR.new({:csr => @csr_dsa})
276
- csr.bit_strength.should == 1024
283
+ csr.bit_length.should == 1024
277
284
  end
278
285
 
279
286
  it "loads a csr with load_from_file" do
@@ -292,20 +299,20 @@ describe R509::CSR do
292
299
  csr.curve_name.should == "secp384r1"
293
300
  end
294
301
  it "generates a CSR with default curve" do
295
- csr = R509::CSR.new(:type => :ec, :subject => [["CN","ec-test.local"]])
302
+ csr = R509::CSR.new(:type => "EC", :subject => [["CN","ec-test.local"]])
296
303
  csr.curve_name.should == "secp384r1"
297
304
  end
298
305
  it "generates a CSR with explicit curve" do
299
- csr = R509::CSR.new(:type => :ec, :curve_name => "sect283r1", :subject => [["CN","ec-test.local"]])
306
+ csr = R509::CSR.new(:type => "EC", :curve_name => "sect283r1", :subject => [["CN","ec-test.local"]])
300
307
  csr.curve_name.should == "sect283r1"
301
308
  end
302
- it "raises error on bit strength" do
309
+ it "raises error on bit length" do
303
310
  csr = R509::CSR.new(:csr => @ec_csr2_der)
304
- expect { csr.bit_strength }.to raise_error(R509::R509Error,'Bit strength is not available for EC at this time.')
311
+ expect { csr.bit_length }.to raise_error(R509::R509Error,'Bit length is not available for EC at this time.')
305
312
  end
306
313
  it "returns the key algorithm" do
307
314
  csr = R509::CSR.new(:csr => @ec_csr2_pem)
308
- csr.key_algorithm.should == :ec
315
+ csr.key_algorithm.should == "EC"
309
316
  end
310
317
  it "returns the public key" do
311
318
  csr = R509::CSR.new(:csr => @ec_csr2_pem)
@@ -317,7 +324,7 @@ describe R509::CSR do
317
324
  csr.ec?.should == true
318
325
  end
319
326
  it "sets alternate signature properly for EC" do
320
- csr = R509::CSR.new(:message_digest => 'sha256', :type => :ec, :subject => [["CN","ec-signature-alg.test"]])
327
+ csr = R509::CSR.new(:message_digest => 'sha256', :type => "EC", :subject => [["CN","ec-signature-alg.test"]])
321
328
  csr.message_digest.name.should == 'sha256'
322
329
  csr.signature_algorithm.should == 'ecdsa-with-SHA256'
323
330
  end
@@ -340,7 +347,7 @@ describe R509::CSR do
340
347
  end
341
348
  it "returns RSA key algorithm for RSA CSR" do
342
349
  csr = R509::CSR.new({ :csr => @csr })
343
- csr.key_algorithm.should == :rsa
350
+ csr.key_algorithm.should == "RSA"
344
351
  end
345
352
  end
346
353
 
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require 'r509/engine'
3
+
4
+ # boilerplate to reset the singleton between tests
5
+ class R509::Engine
6
+ def reset
7
+ @engines = {}
8
+ end
9
+ end
10
+
11
+ describe R509::Engine do
12
+ before :each do
13
+ R509::Engine.instance.reset
14
+ end
15
+
16
+ it "is a singleton" do
17
+ expect { R509::Engine.new }.to raise_error(StandardError)
18
+ end
19
+
20
+ it "raises an error if you don't supply an :so_path and :id" do
21
+ expect { R509::Engine.instance.load("not even a hash") }.to raise_error(ArgumentError, "You must supply a hash with both :so_path and :id")
22
+ expect { R509::Engine.instance.load({:so_path => "path"}) }.to raise_error(ArgumentError, "You must supply a hash with both :so_path and :id")
23
+ end
24
+
25
+ it "load returns a new engine" do
26
+ OpenSSL::Engine.should_receive(:load)
27
+ engine_double = double('engine')
28
+ OpenSSL::Engine.should_receive(:by_id).and_yield(engine_double).and_return(engine_double)
29
+ engine_double.should_receive(:ctrl_cmd).with("SO_PATH", "/some/path")
30
+ engine_double.should_receive(:ctrl_cmd).with("ID", "mocked")
31
+ engine_double.should_receive(:ctrl_cmd).with("LOAD")
32
+ engine = R509::Engine.instance.load(:so_path => "/some/path", :id => "mocked")
33
+ engine.should == engine_double
34
+ end
35
+
36
+ it "load returns pre-existing engine" do
37
+ OpenSSL::Engine.should_receive(:load)
38
+ OpenSSL::Engine.should_receive(:by_id).and_return("mocked_engine")
39
+ R509::Engine.instance.load(:so_path => "/some/path", :id => "mocked")
40
+ engine = R509::Engine.instance.load(:so_path => "/some/path", :id => "mocked")
41
+ engine.should == 'mocked_engine'
42
+ end
43
+
44
+ it "returns an engine with []" do
45
+ OpenSSL::Engine.should_receive(:load)
46
+ OpenSSL::Engine.should_receive(:by_id).and_return("mocked_engine")
47
+ R509::Engine.instance.load(:so_path => "/some/path", :id => "mocked")
48
+ R509::Engine.instance["mocked"].should == "mocked_engine"
49
+ R509::Engine.instance["other"].should be_nil
50
+ end
51
+ end
@@ -69,6 +69,8 @@ module TestFixtures
69
69
 
70
70
  CSR_INVALID_SIGNATURE = read_fixture('csr_invalid_signature.pem')
71
71
 
72
+ SPKI_INVALID_SIGNATURE = "MIIBOjCBpDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAnk0rEYEFZS0KaOq1xb4pJbWMuTFbji9a5GDjgw8jDQh3YS5968sXqmTZS9Vm0ctOmicUka0MOfSwlVEzvLLh/5Na7A8dreOrGI3Qck9AsAEfCBWACZ4hTOfm23rBQYsR9FkEhDAVUXZm2JBPZM38c5QVV37NNr2zCD+CIoXhCjMCAwEAARYAMA0GCSqGSIb3DQEBBQUAA4GBAENx9YXoEYTCOkC9SX4qQFmRgCTFhZVB6E+aAW20KIndAchIctegOR4mzCHAgizmvgmboevG9meKOVZJRWLucElIOnXBFV7BORsn9HP8Bhc1ct3wip2Bwp9wFPM8MS7FyA/Csyze8eKh5wedXWTmPqHMcoUz2QP0lSu1iRZGLRps"
73
+
72
74
  CSR_DER = read_fixture('csr1.der')
73
75
 
74
76
  CSR_NEWLINES = read_fixture('csr1_newlines.pem')
@@ -128,6 +130,9 @@ module TestFixtures
128
130
  TEST_CA_OCSP_CERT = read_fixture('test_ca_ocsp.cer')
129
131
  TEST_CA_OCSP_KEY = read_fixture('test_ca_ocsp.key')
130
132
 
133
+ TEST_CA_CRL_CERT = read_fixture('test_ca_crl.cer')
134
+ TEST_CA_CRL_KEY = read_fixture('test_ca_crl.key')
135
+
131
136
  TEST_CA_SUBROOT_CERT = read_fixture('test_ca_subroot.cer')
132
137
  TEST_CA_SUBROOT_KEY = read_fixture('test_ca_subroot.key')
133
138
 
@@ -161,6 +166,10 @@ module TestFixtures
161
166
  R509::Cert.new(:cert => TEST_CA_CERT, :key => TEST_CA_KEY)
162
167
  end
163
168
 
169
+ def self.test_ca_crl_delegate
170
+ R509::Cert.new(:cert => TEST_CA_CRL_CERT, :key => TEST_CA_CRL_KEY)
171
+ end
172
+
164
173
  def self.test_ca_ec_cert
165
174
  R509::Cert.new(:cert => TEST_CA_EC_CERT, :key => TEST_CA_EC_KEY)
166
175
  end
@@ -174,55 +183,54 @@ module TestFixtures
174
183
  end
175
184
 
176
185
  def self.test_ca_server_profile
177
- R509::Config::CAProfile.new(
178
- :basic_constraints => {"ca" => false },
179
- :key_usage => ["digitalSignature","keyEncipherment"],
180
- :extended_key_usage => ["serverAuth"],
181
- :certificate_policies => [
182
- { "policy_identifier" => "2.16.840.1.12345.1.2.3.4.1",
183
- "cps_uris" => ["http://example.com/cps","http://other.com/cps"],
184
- "user_notices" => [ {"explicit_text" => "thing", "organization" => "my org", "notice_numbers" => "1,2,3,4"} ]
185
- }
186
- ]
186
+ R509::Config::CertProfile.new(
187
+ :basic_constraints => R509::Cert::Extensions::BasicConstraints.new({:ca => false }),
188
+ :key_usage => R509::Cert::Extensions::KeyUsage.new(:value => ["digitalSignature","keyEncipherment"]),
189
+ :extended_key_usage => R509::Cert::Extensions::ExtendedKeyUsage.new(:value => ["serverAuth"]),
190
+ :certificate_policies => R509::Cert::Extensions::CertificatePolicies.new(:value => [
191
+ { :policy_identifier => "2.16.840.1.12345.1.2.3.4.1",
192
+ :cps_uris => ["http://example.com/cps","http://other.com/cps"],
193
+ :user_notices => [ {:explicit_text => "thing", :organization => "my org", :notice_numbers => [1,2,3,4]} ]
194
+ }
195
+ ])
187
196
  )
188
197
 
189
198
  end
190
199
 
191
200
  def self.test_ca_server_profile_with_subject_item_policy
192
201
  subject_item_policy = R509::Config::SubjectItemPolicy.new(
193
- "CN" => "required",
194
- "O" => "optional",
195
- "ST" => "required",
196
- "C" => "required",
197
- "OU" => "optional"
202
+ "CN" => { :policy => "required"},
203
+ "O" => { :policy => "optional"},
204
+ "ST" => { :policy => "required"},
205
+ "C" => { :policy => "required"},
206
+ "OU" => { :policy => "optional"}
198
207
  )
199
- R509::Config::CAProfile.new(
200
- :basic_constraints => {"ca" => false },
201
- :key_usage => ["digitalSignature","keyEncipherment"],
202
- :extended_key_usage => ["serverAuth"],
203
- :certificate_policies => [
204
- { "policy_identifier" => "2.16.840.1.12345.1.2.3.4.1",
205
- "cps_uris" => ["http://example.com/cps","http://other.com/cps"],
206
- "user_notices" => [ {"explicit_text" => "thing", "organization" => "my org", "notice_numbers" => "1,2,3,4"} ]
208
+ R509::Config::CertProfile.new(
209
+ :basic_constraints => R509::Cert::Extensions::BasicConstraints.new({:ca => false }),
210
+ :key_usage => R509::Cert::Extensions::KeyUsage.new(:value => ["digitalSignature","keyEncipherment"]),
211
+ :extended_key_usage => R509::Cert::Extensions::ExtendedKeyUsage.new(:value => ["serverAuth"]),
212
+ :certificate_policies => R509::Cert::Extensions::CertificatePolicies.new(:value => [
213
+ { :policy_identifier => "2.16.840.1.12345.1.2.3.4.1",
214
+ :cps_uris => ["http://example.com/cps","http://other.com/cps"],
215
+ :user_notices => [ {:explicit_text => "thing", :organization => "my org", :notice_numbers => [1,2,3,4]} ]
207
216
  }
208
- ],
217
+ ]),
209
218
  :subject_item_policy => subject_item_policy
210
219
  )
211
220
  end
212
221
 
213
222
  def self.test_ca_subroot_profile
214
- R509::Config::CAProfile.new(
215
- :basic_constraints => {"ca" => true, "path_length" => 0 },
216
- :key_usage => ["keyCertSign","cRLSign"],
217
- :extended_key_usage => [],
223
+ R509::Config::CertProfile.new(
224
+ :basic_constraints => {:ca => true, :path_length => 0 },
225
+ :key_usage => {:value => ["keyCertSign","cRLSign"]},
218
226
  :certificate_policies => nil)
219
227
  end
220
228
 
221
229
  def self.test_ca_ocspsigner_profile
222
- R509::Config::CAProfile.new(
223
- :basic_constraints => { "ca" => false },
224
- :key_usage => ["digitalSignature"],
225
- :extended_key_usage => ["OCSPSigning"],
230
+ R509::Config::CertProfile.new(
231
+ :basic_constraints => { :ca => false },
232
+ :key_usage => {:value => ["digitalSignature"]},
233
+ :extended_key_usage => {:value => ["OCSPSigning"]},
226
234
  :certificate_policies => nil)
227
235
  end
228
236
 
@@ -235,8 +243,6 @@ module TestFixtures
235
243
 
236
244
  opts = {
237
245
  :ca_cert => test_ca_cert(),
238
- :cdp_location => ['http://crl.domain.com/test_ca.crl'],
239
- :ocsp_location => ['http://ocsp.domain.com'],
240
246
  :ocsp_start_skew_seconds => 3600,
241
247
  :ocsp_validity_hours => 48,
242
248
  :crl_list_file => crl_list_sio,
@@ -261,8 +267,6 @@ module TestFixtures
261
267
 
262
268
  opts = {
263
269
  :ca_cert => test_ca_cert(),
264
- :cdp_location => ['http://crl.domain.com/test_ca.crl'],
265
- :ocsp_location => ['http://ocsp.domain.com'],
266
270
  :ocsp_start_skew_seconds => 3600,
267
271
  :ocsp_validity_hours => 48,
268
272
  :crl_list_file => crl_list_sio,
@@ -279,8 +283,6 @@ module TestFixtures
279
283
 
280
284
  opts = {
281
285
  :ca_cert => test_ca_ec_cert(),
282
- :cdp_location => ['http://crl.domain.com/test_ca.crl'],
283
- :ocsp_location => ['http://ocsp.domain.com'],
284
286
  :ocsp_start_skew_seconds => 3600,
285
287
  :ocsp_validity_hours => 48,
286
288
  :crl_list_file => crl_list_sio,
@@ -297,8 +299,6 @@ module TestFixtures
297
299
 
298
300
  opts = {
299
301
  :ca_cert => test_ca_dsa_cert(),
300
- :cdp_location => ['http://crl.domain.com/test_ca.crl'],
301
- :ocsp_location => ['http://ocsp.domain.com'],
302
302
  :ocsp_start_skew_seconds => 3600,
303
303
  :ocsp_validity_hours => 48,
304
304
  :crl_list_file => crl_list_sio,
@@ -21,4 +21,4 @@ BZB3DR71BJTP/YUOD6uWOFSh8didm3kHNbAvG4X/xWyj07n70Cof0PBDGtw8QKlt
21
21
  CBydpPHBeew14n0PXXLB8jrDd6PtlKvKWrLVs9igASBuW584chaWNw039zxRKoqq
22
22
  PsMwIw+1he4Bax4hH4fM4wQOFpnhk5Y34VmdZqo1JtF7Vn41ghGwsXVswvl6wPC1
23
23
  g4+GUUwJtQ6cJyMmN4sIHDbCFTOWBlUijvMrvl3wxncqDmOp
24
- -----END CERTIFICATE-----
24
+ -----END CERTIFICATE-----
@@ -1,15 +1,11 @@
1
- certificate_authorities: {
2
- test_ca: {
3
- ca_cert: {
4
- cert: 'test_ca.cer',
5
- key: 'test_ca.key'
6
- }
7
- },
8
- second_ca: {
9
- ca_cert: {
10
- cert: 'test_ca.cer',
11
- key: 'test_ca.key'
12
- }
13
- }
14
- }
15
- config_is_string: "this is bogus"
1
+ ---
2
+ certificate_authorities:
3
+ test_ca:
4
+ ca_cert:
5
+ cert: test_ca.cer
6
+ key: test_ca.key
7
+ second_ca:
8
+ ca_cert:
9
+ cert: test_ca.cer
10
+ key: test_ca.key
11
+ config_is_string: this is bogus