1
+ #!/usr/bin/env python
2
+ #
3
+ # Copyright 2019-2025 Flavio Garcia
4
+ # Copyright 2016-2017 Veeti Paananen under MIT License
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ import unittest
19
+ from unittest .mock import patch , MagicMock
20
+ from cryptography import x509
21
+ from cryptography .hazmat .primitives import serialization , hashes
22
+ from cryptography .hazmat .primitives .asymmetric import rsa
23
+ import datetime
24
+ import warnings
25
+
26
+ from automatoes .issue import EXPIRATION_FORMAT
27
+
28
+
29
+ class IssueTestCase (unittest .TestCase ):
30
+
31
+ def test_certificate_expiration_uses_utc_property (self ):
32
+ """Test that certificate expiration formatting uses not_valid_after_utc."""
33
+ # Generate a test certificate
34
+ private_key = rsa .generate_private_key (
35
+ public_exponent = 65537 ,
36
+ key_size = 2048 ,
37
+ )
38
+
39
+ subject = issuer = x509 .Name ([
40
+ x509 .NameAttribute (x509 .NameOID .COUNTRY_NAME , 'US' ),
41
+ x509 .NameAttribute (x509 .NameOID .COMMON_NAME , 'test.example.com' ),
42
+ ])
43
+
44
+ # Create expiration date in UTC
45
+ expiration_date = datetime .datetime (2025 , 12 , 31 , 23 , 59 , 59 , tzinfo = datetime .timezone .utc )
46
+
47
+ cert = x509 .CertificateBuilder ().subject_name (
48
+ subject
49
+ ).issuer_name (
50
+ issuer
51
+ ).public_key (
52
+ private_key .public_key ()
53
+ ).serial_number (
54
+ x509 .random_serial_number ()
55
+ ).not_valid_before (
56
+ datetime .datetime .now ()
57
+ ).not_valid_after (
58
+ expiration_date
59
+ ).sign (private_key , hashes .SHA256 ())
60
+
61
+ # Test that not_valid_after_utc returns UTC-aware datetime
62
+ self .assertIsNotNone (cert .not_valid_after_utc )
63
+ self .assertIsNotNone (cert .not_valid_after_utc .tzinfo )
64
+
65
+ # Test that formatting works correctly with not_valid_after_utc
66
+ formatted_expiration = cert .not_valid_after_utc .strftime (EXPIRATION_FORMAT )
67
+ self .assertEqual (formatted_expiration , "2025-12-31" )
68
+
69
+ # Test that not_valid_after (deprecated) produces warnings
70
+ with warnings .catch_warnings (record = True ) as w :
71
+ warnings .simplefilter ("always" )
72
+ _ = cert .not_valid_after
73
+ # Check that a deprecation warning was issued
74
+ self .assertTrue (len (w ) > 0 )
75
+ self .assertTrue (any ("deprecated" in str (warning .message ).lower () for warning in w ))
76
+
77
+
78
+ if __name__ == "__main__" :
79
+ unittest .main ()
0 commit comments