1require_relative "utils"
2
3if defined?(OpenSSL)
4
5class OpenSSL::TestX509CRL < Test::Unit::TestCase
6  def setup
7    @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
8    @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
9    @dsa256  = OpenSSL::TestUtils::TEST_KEY_DSA256
10    @dsa512  = OpenSSL::TestUtils::TEST_KEY_DSA512
11    @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
12    @ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
13    @ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
14  end
15
16  def teardown
17  end
18
19  def issue_crl(*args)
20    OpenSSL::TestUtils.issue_crl(*args)
21  end
22
23  def issue_cert(*args)
24    OpenSSL::TestUtils.issue_cert(*args)
25  end
26
27  def test_basic
28    now = Time.at(Time.now.to_i)
29
30    cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],
31                      nil, nil, OpenSSL::Digest::SHA1.new)
32    crl = issue_crl([], 1, now, now+1600, [],
33                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)
34    assert_equal(1, crl.version)
35    assert_equal(cert.issuer.to_der, crl.issuer.to_der)
36    assert_equal(now, crl.last_update)
37    assert_equal(now+1600, crl.next_update)
38
39    crl = OpenSSL::X509::CRL.new(crl.to_der)
40    assert_equal(1, crl.version)
41    assert_equal(cert.issuer.to_der, crl.issuer.to_der)
42    assert_equal(now, crl.last_update)
43    assert_equal(now+1600, crl.next_update)
44  end
45
46  def test_revoked
47
48    # CRLReason ::= ENUMERATED {
49    #      unspecified             (0),
50    #      keyCompromise           (1),
51    #      cACompromise            (2),
52    #      affiliationChanged      (3),
53    #      superseded              (4),
54    #      cessationOfOperation    (5),
55    #      certificateHold         (6),
56    #      removeFromCRL           (8),
57    #      privilegeWithdrawn      (9),
58    #      aACompromise           (10) }
59
60    now = Time.at(Time.now.to_i)
61    revoke_info = [
62      [1, Time.at(0),          1],
63      [2, Time.at(0x7fffffff), 2],
64      [3, now,                 3],
65      [4, now,                 4],
66      [5, now,                 5],
67    ]
68    cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
69                      nil, nil, OpenSSL::Digest::SHA1.new)
70    crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [],
71                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)
72    revoked = crl.revoked
73    assert_equal(5, revoked.size)
74    assert_equal(1, revoked[0].serial)
75    assert_equal(2, revoked[1].serial)
76    assert_equal(3, revoked[2].serial)
77    assert_equal(4, revoked[3].serial)
78    assert_equal(5, revoked[4].serial)
79
80    assert_equal(Time.at(0), revoked[0].time)
81    assert_equal(Time.at(0x7fffffff), revoked[1].time)
82    assert_equal(now, revoked[2].time)
83    assert_equal(now, revoked[3].time)
84    assert_equal(now, revoked[4].time)
85
86    assert_equal("CRLReason", revoked[0].extensions[0].oid)
87    assert_equal("CRLReason", revoked[1].extensions[0].oid)
88    assert_equal("CRLReason", revoked[2].extensions[0].oid)
89    assert_equal("CRLReason", revoked[3].extensions[0].oid)
90    assert_equal("CRLReason", revoked[4].extensions[0].oid)
91
92    assert_equal("Key Compromise", revoked[0].extensions[0].value)
93    assert_equal("CA Compromise", revoked[1].extensions[0].value)
94    assert_equal("Affiliation Changed", revoked[2].extensions[0].value)
95    assert_equal("Superseded", revoked[3].extensions[0].value)
96    assert_equal("Cessation Of Operation", revoked[4].extensions[0].value)
97
98    assert_equal(false, revoked[0].extensions[0].critical?)
99    assert_equal(false, revoked[1].extensions[0].critical?)
100    assert_equal(false, revoked[2].extensions[0].critical?)
101    assert_equal(false, revoked[3].extensions[0].critical?)
102    assert_equal(false, revoked[4].extensions[0].critical?)
103
104    assert_equal("Key Compromise", revoked[0].extensions[0].value)
105    assert_equal("CA Compromise", revoked[1].extensions[0].value)
106    assert_equal("Affiliation Changed", revoked[2].extensions[0].value)
107    assert_equal("Superseded", revoked[3].extensions[0].value)
108    assert_equal("Cessation Of Operation", revoked[4].extensions[0].value)
109
110    revoke_info = (1..1000).collect{|i| [i, now, 0] }
111    crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [],
112                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)
113    revoked = crl.revoked
114    assert_equal(1000, revoked.size)
115    assert_equal(1, revoked[0].serial)
116    assert_equal(1000, revoked[999].serial)
117  end
118
119  def test_extension
120    cert_exts = [
121      ["basicConstraints", "CA:TRUE", true],
122      ["subjectKeyIdentifier", "hash", false],
123      ["authorityKeyIdentifier", "keyid:always", false],
124      ["subjectAltName", "email:xyzzy@ruby-lang.org", false],
125      ["keyUsage", "cRLSign, keyCertSign", true],
126    ]
127    crl_exts = [
128      ["authorityKeyIdentifier", "keyid:always", false],
129      ["issuerAltName", "issuer:copy", false],
130    ]
131
132    cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, cert_exts,
133                      nil, nil, OpenSSL::Digest::SHA1.new)
134    crl = issue_crl([], 1, Time.now, Time.now+1600, crl_exts,
135                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)
136    exts = crl.extensions
137    assert_equal(3, exts.size)
138    assert_equal("1", exts[0].value)
139    assert_equal("crlNumber", exts[0].oid)
140    assert_equal(false, exts[0].critical?)
141
142    assert_equal("authorityKeyIdentifier", exts[1].oid)
143    keyid = OpenSSL::TestUtils.get_subject_key_id(cert)
144    assert_match(/^keyid:#{keyid}/, exts[1].value)
145    assert_equal(false, exts[1].critical?)
146
147    assert_equal("issuerAltName", exts[2].oid)
148    assert_equal("email:xyzzy@ruby-lang.org", exts[2].value)
149    assert_equal(false, exts[2].critical?)
150
151    crl = OpenSSL::X509::CRL.new(crl.to_der)
152    exts = crl.extensions
153    assert_equal(3, exts.size)
154    assert_equal("1", exts[0].value)
155    assert_equal("crlNumber", exts[0].oid)
156    assert_equal(false, exts[0].critical?)
157
158    assert_equal("authorityKeyIdentifier", exts[1].oid)
159    keyid = OpenSSL::TestUtils.get_subject_key_id(cert)
160    assert_match(/^keyid:#{keyid}/, exts[1].value)
161    assert_equal(false, exts[1].critical?)
162
163    assert_equal("issuerAltName", exts[2].oid)
164    assert_equal("email:xyzzy@ruby-lang.org", exts[2].value)
165    assert_equal(false, exts[2].critical?)
166  end
167
168  def test_crlnumber
169    cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
170                      nil, nil, OpenSSL::Digest::SHA1.new)
171    crl = issue_crl([], 1, Time.now, Time.now+1600, [],
172                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)
173    assert_match(1.to_s, crl.extensions[0].value)
174    assert_match(/X509v3 CRL Number:\s+#{1}/m, crl.to_text)
175
176    crl = issue_crl([], 2**32, Time.now, Time.now+1600, [],
177                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)
178    assert_match((2**32).to_s, crl.extensions[0].value)
179    assert_match(/X509v3 CRL Number:\s+#{2**32}/m, crl.to_text)
180
181    crl = issue_crl([], 2**100, Time.now, Time.now+1600, [],
182                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)
183    assert_match(/X509v3 CRL Number:\s+#{2**100}/m, crl.to_text)
184    assert_match((2**100).to_s, crl.extensions[0].value)
185  end
186
187  def test_sign_and_verify
188    cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
189                      nil, nil, OpenSSL::Digest::SHA1.new)
190    crl = issue_crl([], 1, Time.now, Time.now+1600, [],
191                    cert, @rsa2048, OpenSSL::Digest::SHA1.new)
192    assert_equal(false, crl.verify(@rsa1024))
193    assert_equal(true,  crl.verify(@rsa2048))
194    assert_equal(false, crl_error_returns_false { crl.verify(@dsa256) })
195    assert_equal(false, crl_error_returns_false { crl.verify(@dsa512) })
196    crl.version = 0
197    assert_equal(false, crl.verify(@rsa2048))
198
199    cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
200                      nil, nil, OpenSSL::TestUtils::DSA_SIGNATURE_DIGEST.new)
201    crl = issue_crl([], 1, Time.now, Time.now+1600, [],
202                    cert, @dsa512, OpenSSL::TestUtils::DSA_SIGNATURE_DIGEST.new)
203    assert_equal(false, crl_error_returns_false { crl.verify(@rsa1024) })
204    assert_equal(false, crl_error_returns_false { crl.verify(@rsa2048) })
205    assert_equal(false, crl.verify(@dsa256))
206    assert_equal(true,  crl.verify(@dsa512))
207    crl.version = 0
208    assert_equal(false, crl.verify(@dsa512))
209  end
210
211  private
212
213  def crl_error_returns_false
214    yield
215  rescue OpenSSL::X509::CRLError
216    false
217  end
218end
219
220end
221