blob: b44f3456d85c1261c89575aa761d138b4ec05e5b [file] [log] [blame]
Jean-Paul Calderone8b63d452008-03-21 18:31:12 -04001# Copyright (C) Jean-Paul Calderone 2008, All rights reserved
2
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05003"""
4Unit tests for L{OpenSSL.crypto}.
5"""
6
7from unittest import TestCase
8
9from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey, PKeyType
Jean-Paul Calderone78381d22008-03-06 23:35:22 -050010from OpenSSL.crypto import X509, X509Type, X509Name, X509NameType
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -050011from OpenSSL.crypto import X509Req, X509ReqType
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -040012from OpenSSL.crypto import FILETYPE_PEM, load_certificate
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050013
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -050014class _Python23TestCaseHelper:
Jean-Paul Calderone7da26a72008-03-06 00:35:20 -050015 # Python 2.3 compatibility.
16 def assertTrue(self, *a, **kw):
17 return self.failUnless(*a, **kw)
18
19
Jean-Paul Calderone7535dab2008-03-06 18:53:11 -050020 def assertFalse(self, *a, **kw):
21 return self.failIf(*a, **kw)
22
23
24
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -050025class PKeyTests(TestCase, _Python23TestCaseHelper):
26 """
27 Unit tests for L{OpenSSL.crypto.PKey}.
28 """
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050029 def test_construction(self):
30 """
31 L{PKey} takes no arguments and returns a new L{PKeyType} instance.
32 """
33 self.assertRaises(TypeError, PKey, None)
34 key = PKey()
35 self.assertTrue(
36 isinstance(key, PKeyType),
37 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
38
39
40 def test_pregeneration(self):
41 """
42 L{PKeyType.bits} and L{PKeyType.type} return C{0} before the key is
43 generated.
44 """
45 key = PKey()
46 self.assertEqual(key.type(), 0)
47 self.assertEqual(key.bits(), 0)
48
49
50 def test_failedGeneration(self):
51 """
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -050052 L{PKeyType.generate_key} takes two arguments, the first giving the key
53 type as one of L{TYPE_RSA} or L{TYPE_DSA} and the second giving the
54 number of bits to generate. If an invalid type is specified or
55 generation fails, L{Error} is raised. If an invalid number of bits is
56 specified, L{ValueError} or L{Error} is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050057 """
58 key = PKey()
59 self.assertRaises(TypeError, key.generate_key)
60 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
61 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
62 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -050063
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -050064 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
65 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -050066
67 # XXX RSA generation for small values of bits is fairly buggy in a wide
68 # range of OpenSSL versions. I need to figure out what the safe lower
69 # bound for a reasonable number of OpenSSL versions is and explicitly
70 # check for that in the wrapper. The failure behavior is typically an
71 # infinite loop inside OpenSSL.
72
73 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050074
75 # XXX DSA generation seems happy with any number of bits. The DSS
76 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
77 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -050078 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050079 # So, it doesn't seem possible to make generate_key fail for
80 # TYPE_DSA with a bits argument which is at least an int.
81
82 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
83
84
85 def test_rsaGeneration(self):
86 """
87 L{PKeyType.generate_key} generates an RSA key when passed
88 L{TYPE_RSA} as a type and a reasonable number of bits.
89 """
90 bits = 128
91 key = PKey()
92 key.generate_key(TYPE_RSA, bits)
93 self.assertEqual(key.type(), TYPE_RSA)
94 self.assertEqual(key.bits(), bits)
95
96
97 def test_dsaGeneration(self):
98 """
99 L{PKeyType.generate_key} generates a DSA key when passed
100 L{TYPE_DSA} as a type and a reasonable number of bits.
101 """
102 # 512 is a magic number. The DSS (Digital Signature Standard)
103 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
104 # will silently promote any value below 512 to 512.
105 bits = 512
106 key = PKey()
107 key.generate_key(TYPE_DSA, bits)
108 self.assertEqual(key.type(), TYPE_DSA)
109 self.assertEqual(key.bits(), bits)
110
111
112 def test_regeneration(self):
113 """
114 L{PKeyType.generate_key} can be called multiple times on the same
115 key to generate new keys.
116 """
117 key = PKey()
118 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
119 key.generate_key(type, bits)
120 self.assertEqual(key.type(), type)
121 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500122
123
124
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500125class X509NameTests(TestCase, _Python23TestCaseHelper):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500126 """
127 Unit tests for L{OpenSSL.crypto.X509Name}.
128 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500129 def _x509name(self, **attrs):
130 # XXX There's no other way to get a new X509Name yet.
131 name = X509().get_subject()
132 attrs = attrs.items()
133 # Make the order stable - order matters!
134 attrs.sort(lambda (k1, v1), (k2, v2): cmp(v1, v2))
135 for k, v in attrs:
136 setattr(name, k, v)
137 return name
138
139
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500140 def test_attributes(self):
141 """
142 L{X509NameType} instances have attributes for each standard (?)
143 X509Name field.
144 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500145 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500146 name.commonName = "foo"
147 self.assertEqual(name.commonName, "foo")
148 self.assertEqual(name.CN, "foo")
149 name.CN = "baz"
150 self.assertEqual(name.commonName, "baz")
151 self.assertEqual(name.CN, "baz")
152 name.commonName = "bar"
153 self.assertEqual(name.commonName, "bar")
154 self.assertEqual(name.CN, "bar")
155 name.CN = "quux"
156 self.assertEqual(name.commonName, "quux")
157 self.assertEqual(name.CN, "quux")
158
159
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500160 def test_copy(self):
161 """
162 L{X509Name} creates a new L{X509NameType} instance with all the same
163 attributes as an existing L{X509NameType} instance when called with
164 one.
165 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500166 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500167
168 copy = X509Name(name)
169 self.assertEqual(copy.commonName, "foo")
170 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500171
172 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500173 copy.commonName = "baz"
174 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500175
176 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500177 name.emailAddress = "quux@example.com"
178 self.assertEqual(copy.emailAddress, "bar@example.com")
179
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500180
181 def test_repr(self):
182 """
183 L{repr} passed an L{X509NameType} instance should return a string
184 containing a description of the type and the NIDs which have been set
185 on it.
186 """
187 name = self._x509name(commonName="foo", emailAddress="bar")
188 self.assertEqual(
189 repr(name),
190 "<X509Name object '/emailAddress=bar/CN=foo'>")
191
192
193 def test_comparison(self):
194 """
195 L{X509NameType} instances should compare based on their NIDs.
196 """
197 def _equality(a, b, assertTrue, assertFalse):
198 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
199 assertFalse(a != b)
200 assertTrue(b == a)
201 assertFalse(b != a)
202
203 def assertEqual(a, b):
204 _equality(a, b, self.assertTrue, self.assertFalse)
205
206 # Instances compare equal to themselves.
207 name = self._x509name()
208 assertEqual(name, name)
209
210 # Empty instances should compare equal to each other.
211 assertEqual(self._x509name(), self._x509name())
212
213 # Instances with equal NIDs should compare equal to each other.
214 assertEqual(self._x509name(commonName="foo"),
215 self._x509name(commonName="foo"))
216
217 # Instance with equal NIDs set using different aliases should compare
218 # equal to each other.
219 assertEqual(self._x509name(commonName="foo"),
220 self._x509name(CN="foo"))
221
222 # Instances with more than one NID with the same values should compare
223 # equal to each other.
224 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
225 self._x509name(commonName="foo", OU="bar"))
226
227 def assertNotEqual(a, b):
228 _equality(a, b, self.assertFalse, self.assertTrue)
229
230 # Instances with different values for the same NID should not compare
231 # equal to each other.
232 assertNotEqual(self._x509name(CN="foo"),
233 self._x509name(CN="bar"))
234
235 # Instances with different NIDs should not compare equal to each other.
236 assertNotEqual(self._x509name(CN="foo"),
237 self._x509name(OU="foo"))
238
239 def _inequality(a, b, assertTrue, assertFalse):
240 assertTrue(a < b)
241 assertTrue(a <= b)
242 assertTrue(b > a)
243 assertTrue(b >= a)
244 assertFalse(a > b)
245 assertFalse(a >= b)
246 assertFalse(b < a)
247 assertFalse(b <= a)
248
249 def assertLessThan(a, b):
250 _inequality(a, b, self.assertTrue, self.assertFalse)
251
252 # An X509Name with a NID with a value which sorts less than the value
253 # of the same NID on another X509Name compares less than the other
254 # X509Name.
255 assertLessThan(self._x509name(CN="abc"),
256 self._x509name(CN="def"))
257
258 def assertGreaterThan(a, b):
259 _inequality(a, b, self.assertFalse, self.assertTrue)
260
261 # An X509Name with a NID with a value which sorts greater than the
262 # value of the same NID on another X509Name compares greater than the
263 # other X509Name.
264 assertGreaterThan(self._x509name(CN="def"),
265 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500266
267
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400268 def test_hash(self):
269 """
270 L{X509Name.hash} returns an integer hash based on the value of the
271 name.
272 """
273 a = self._x509name(CN="foo")
274 b = self._x509name(CN="foo")
275 self.assertEqual(a.hash(), b.hash())
276 a.CN = "bar"
277 self.assertNotEqual(a.hash(), b.hash())
278
279
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400280 def test_der(self):
281 """
282 L{X509Name.der} returns the DER encoded form of the name.
283 """
284 a = self._x509name(CN="foo", C="US")
285 self.assertEqual(
286 a.der(),
287 '0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
288 '1\x0c0\n\x06\x03U\x04\x03\x13\x03foo')
289
290
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400291 def test_get_components(self):
292 """
293 L{X509Name.get_components} returns a C{list} of two-tuples of C{str}
294 giving the NIDs and associated values which make up the name.
295 """
296 a = self._x509name()
297 self.assertEqual(a.get_components(), [])
298 a.CN = "foo"
299 self.assertEqual(a.get_components(), [("CN", "foo")])
300 a.organizationalUnitName = "bar"
301 self.assertEqual(
302 a.get_components(),
303 [("CN", "foo"), ("OU", "bar")])
304
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400305
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400306class _PKeyInteractionTestsMixin:
307 """
308 Tests which involve another thing and a PKey.
309 """
310 def signable(self):
311 """
312 Return something with a C{set_pubkey}, C{set_pubkey}, and C{sign} method.
313 """
314 raise NotImplementedError()
315
316
317 def test_signWithUngenerated(self):
318 """
319 L{X509Req.sign} raises L{ValueError} when pass a L{PKey} with no parts.
320 """
321 request = self.signable()
322 key = PKey()
323 self.assertRaises(ValueError, request.sign, key, 'MD5')
324
325
326 def test_signWithPublicKey(self):
327 """
328 L{X509Req.sign} raises L{ValueError} when pass a L{PKey} with no
329 private part as the signing key.
330 """
331 request = self.signable()
332 key = PKey()
333 key.generate_key(TYPE_RSA, 512)
334 request.set_pubkey(key)
335 pub = request.get_pubkey()
336 self.assertRaises(ValueError, request.sign, pub, 'MD5')
337
338
339
340class X509ReqTests(TestCase, _PKeyInteractionTestsMixin, _Python23TestCaseHelper):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500341 """
342 Tests for L{OpenSSL.crypto.X509Req}.
343 """
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400344 def signable(self):
345 """
346 Create and return a new L{X509Req}.
347 """
348 return X509Req()
349
350
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500351 def test_construction(self):
352 """
353 L{X509Req} takes no arguments and returns an L{X509ReqType} instance.
354 """
355 request = X509Req()
356 self.assertTrue(
357 isinstance(request, X509ReqType),
358 "%r is of type %r, should be %r" % (request, type(request), X509ReqType))
359
360
361 def test_get_subject(self):
362 """
363 L{X509ReqType.get_subject} returns an L{X509Name} for the subject of
364 the request and which is valid even after the request object is
365 otherwise dead.
366 """
367 request = X509Req()
368 subject = request.get_subject()
369 self.assertTrue(
370 isinstance(subject, X509NameType),
371 "%r is of type %r, should be %r" % (subject, type(subject), X509NameType))
372 subject.commonName = "foo"
373 self.assertEqual(request.get_subject().commonName, "foo")
374 del request
375 subject.commonName = "bar"
376 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500377
378
379
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400380class X509Tests(TestCase, _PKeyInteractionTestsMixin, _Python23TestCaseHelper):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500381 """
382 Tests for L{OpenSSL.crypto.X509}.
383 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -0400384 pemData = """
385-----BEGIN CERTIFICATE-----
386MIICfTCCAeYCAQEwDQYJKoZIhvcNAQEEBQAwgYYxCzAJBgNVBAYTAlVTMRkwFwYD
387VQQDExBweW9wZW5zc2wuc2YubmV0MREwDwYDVQQHEwhOZXcgWW9yazESMBAGA1UE
388ChMJUHlPcGVuU1NMMREwDwYDVQQIEwhOZXcgWW9yazEQMA4GCSqGSIb3DQEJARYB
389IDEQMA4GA1UECxMHVGVzdGluZzAeFw0wODAzMjUxOTA0MTNaFw0wOTAzMjUxOTA0
390MTNaMIGGMQswCQYDVQQGEwJVUzEZMBcGA1UEAxMQcHlvcGVuc3NsLnNmLm5ldDER
391MA8GA1UEBxMITmV3IFlvcmsxEjAQBgNVBAoTCVB5T3BlblNTTDERMA8GA1UECBMI
392TmV3IFlvcmsxEDAOBgkqhkiG9w0BCQEWASAxEDAOBgNVBAsTB1Rlc3RpbmcwgZ8w
393DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSwBsUWkXdqg6tnXy8H8hA1
394msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nAE0zhmHJELcM8gUTIlXv/
395cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXNxQn5ecR0UYSOWj6TTGXB
3969VyUMQzCClcBAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAmm0Vzvv1O91WLl2LnF2P
397q55LJdOnJbCCXIgxLdoVmvYAz1ZJq1eGKgKWI5QLgxiSzJLEU7KK//aVfiZzoCd5
398RipBiEEMEV4eAY317bHPwPP+4Bj9t0l8AsDLseC5vLRHgxrLEu3bn08DYx6imB5Q
399UBj849/xpszEM7BhwKE0GiQ=
400-----END CERTIFICATE-----
401-----BEGIN RSA PRIVATE KEY-----
402MIICXAIBAAKBgQDaemNe1syksAbFFpF3aoOrZ18vB/IQNZrAjFqXPv9iieJm7+Tc
403g+lA/v0qmoEKrpT2xfwxXmvZwBNM4ZhyRC3DPIFEyJV7/3IA1p5iuMY/GJI1VIgn
404aikQCnrsyxtaRpsMBeZRniaVzcUJ+XnEdFGEjlo+k0xlwfVclDEMwgpXAQIDAQAB
405AoGBALi0a7pMQqqgnriVAdpBVJveQtxSDVWi2/gZMKVZfzNheuSnv4amhtaKPKJ+
406CMZtHkcazsE2IFvxRN/kgato9H3gJqq8nq2CkdpdLNVKBoxiCtkLfutdY4SQLtoY
407USN7exk131pchsAJXYlR6mCW+ZP+E523cNwpPgsyKxVbmXSBAkEA9470fy2W0jFM
408taZFslpntKSzbvn6JmdtjtvWrM1bBaeeqFiGBuQFYg46VaCUaeRWYw02jmYAsDYh
409ZQavmXThaQJBAOHtlAQ0IJJEiMZr6vtVPH32fmbthSv1AUSYPzKqdlQrUnOXPQXu
410z70cFoLG1TvPF5rBxbOkbQ/s8/ka5ZjPfdkCQCeC7YsO36+UpsWnUCBzRXITh4AC
4117eYLQ/U1KUJTVF/GrQ/5cQrQgftwgecAxi9Qfmk4xqhbp2h4e0QAmS5I9WECQH02
4120QwrX8nxFeTytr8pFGezj4a4KVCdb2B3CL+p3f70K7RIo9d/7b6frJI6ZL/LHQf2
413UP4pKRDkgKsVDx7MELECQGm072/Z7vmb03h/uE95IYJOgY4nfmYs0QKA9Is18wUz
414DpjfE33p0Ha6GO1VZRIQoqE24F8o5oimy3BEjryFuw4=
415-----END RSA PRIVATE KEY-----
416"""
417
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400418 def signable(self):
419 """
420 Create and return a new L{X509}.
421 """
422 return X509()
423
424
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500425 def test_construction(self):
426 """
427 L{X509} takes no arguments and returns an instance of L{X509Type}.
428 """
429 certificate = X509()
430 self.assertTrue(
431 isinstance(certificate, X509Type),
432 "%r is of type %r, should be %r" % (certificate,
433 type(certificate),
434 X509Type))
435
436
437 def test_serial_number(self):
438 """
439 The serial number of an L{X509Type} can be retrieved and modified with
440 L{X509Type.get_serial_number} and L{X509Type.set_serial_number}.
441 """
442 certificate = X509()
443 self.assertRaises(TypeError, certificate.set_serial_number)
444 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
445 self.assertRaises(TypeError, certificate.set_serial_number, "1")
446 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
447 self.assertEqual(certificate.get_serial_number(), 0)
448 certificate.set_serial_number(1)
449 self.assertEqual(certificate.get_serial_number(), 1)
450 certificate.set_serial_number(2 ** 32 + 1)
451 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
452 certificate.set_serial_number(2 ** 64 + 1)
453 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -0400454 certificate.set_serial_number(2 ** 128 + 1)
455 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
456
457
458 def _setBoundTest(self, which):
459 """
460 L{X509Type.set_notBefore} takes a string in the format of an ASN1
461 GENERALIZEDTIME and sets the beginning of the certificate's validity
462 period to it.
463 """
464 certificate = X509()
465 set = getattr(certificate, 'set_not' + which)
466 get = getattr(certificate, 'get_not' + which)
467
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -0400468 # Starts with no value.
469 self.assertEqual(get(), None)
470
Jean-Paul Calderone525ef802008-03-09 20:39:42 -0400471 # GMT (Or is it UTC?) -exarkun
472 when = "20040203040506Z"
473 set(when)
474 self.assertEqual(get(), when)
475
476 # A plus two hours and thirty minutes offset
477 when = "20040203040506+0530"
478 set(when)
479 self.assertEqual(get(), when)
480
481 # A minus one hour fifteen minutes offset
482 when = "20040203040506-0115"
483 set(when)
484 self.assertEqual(get(), when)
485
486 # An invalid string results in a ValueError
487 self.assertRaises(ValueError, set, "foo bar")
488
489
490 def test_set_notBefore(self):
491 """
492 L{X509Type.set_notBefore} takes a string in the format of an ASN1
493 GENERALIZEDTIME and sets the beginning of the certificate's validity
494 period to it.
495 """
496 self._setBoundTest("Before")
497
498
499 def test_set_notAfter(self):
500 """
501 L{X509Type.set_notAfter} takes a string in the format of an ASN1
502 GENERALIZEDTIME and sets the end of the certificate's validity period
503 to it.
504 """
505 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -0400506
507
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -0400508 def test_get_notBefore(self):
509 """
510 L{X509Type.get_notBefore} returns a string in the format of an ASN1
511 GENERALIZEDTIME even for certificates which store it as UTCTIME
512 internally.
513 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -0400514 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -0400515 self.assertEqual(cert.get_notBefore(), "20080325190413Z")
516
517
518 def test_get_notAfter(self):
519 """
520 L{X509Type.get_notAfter} returns a string in the format of an ASN1
521 GENERALIZEDTIME even for certificates which store it as UTCTIME
522 internally.
523 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -0400524 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -0400525 self.assertEqual(cert.get_notAfter(), "20090325190413Z")
526
527
Jean-Paul Calderone76576d52008-03-24 16:04:46 -0400528 def test_digest(self):
529 """
530 L{X509.digest} returns a string giving ":"-separated hex-encoded words
531 of the digest of the certificate.
532 """
533 cert = X509()
534 self.assertEqual(
535 cert.digest("md5"),
536 "A8:EB:07:F8:53:25:0A:F2:56:05:C5:A5:C4:C4:C7:15")