-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
test_verification.py
140 lines (116 loc) · 4.68 KB
/
test_verification.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
import datetime
import os
from functools import lru_cache
from ipaddress import IPv4Address
import pytest
from cryptography import x509
from cryptography.x509.general_name import DNSName, IPAddress
from cryptography.x509.verification import PolicyBuilder, Store
from tests.x509.test_x509 import _load_cert
@lru_cache(maxsize=1)
def dummy_store() -> Store:
cert = _load_cert(
os.path.join("x509", "cryptography.io.pem"),
x509.load_pem_x509_certificate,
)
return Store([cert])
class TestPolicyBuilder:
def test_time_already_set(self):
with pytest.raises(ValueError):
PolicyBuilder().time(datetime.datetime.now()).time(
datetime.datetime.now()
)
def test_store_already_set(self):
with pytest.raises(ValueError):
PolicyBuilder().store(dummy_store()).store(dummy_store())
def test_max_chain_depth_already_set(self):
with pytest.raises(ValueError):
PolicyBuilder().max_chain_depth(8).max_chain_depth(9)
def test_ipaddress_subject(self):
policy = (
PolicyBuilder()
.store(dummy_store())
.build_server_verifier(IPAddress(IPv4Address("0.0.0.0")))
)
assert policy.subject == IPAddress(IPv4Address("0.0.0.0"))
def test_dnsname_subject(self):
policy = (
PolicyBuilder()
.store(dummy_store())
.build_server_verifier(DNSName("cryptography.io"))
)
assert policy.subject == DNSName("cryptography.io")
def test_subject_bad_types(self):
# Subject must be a supported GeneralName type
with pytest.raises(TypeError):
PolicyBuilder().store(dummy_store()).build_server_verifier(
"cryptography.io" # type: ignore[arg-type]
)
with pytest.raises(TypeError):
PolicyBuilder().store(dummy_store()).build_server_verifier(
"0.0.0.0" # type: ignore[arg-type]
)
with pytest.raises(TypeError):
PolicyBuilder().store(dummy_store()).build_server_verifier(
IPv4Address("0.0.0.0") # type: ignore[arg-type]
)
with pytest.raises(TypeError):
PolicyBuilder().store(dummy_store()).build_server_verifier(None) # type: ignore[arg-type]
def test_builder_pattern(self):
now = datetime.datetime.now().replace(microsecond=0)
store = dummy_store()
max_chain_depth = 16
builder = PolicyBuilder()
builder = builder.time(now)
builder = builder.store(store)
builder = builder.max_chain_depth(max_chain_depth)
verifier = builder.build_server_verifier(DNSName("cryptography.io"))
assert verifier.subject == DNSName("cryptography.io")
assert verifier.validation_time == now
assert verifier.store == store
assert verifier.max_chain_depth == max_chain_depth
def test_build_server_verifier_missing_store(self):
with pytest.raises(
ValueError, match="A server verifier must have a trust store"
):
PolicyBuilder().build_server_verifier(DNSName("cryptography.io"))
class TestStore:
def test_store_rejects_empty_list(self):
with pytest.raises(ValueError):
Store([])
def test_store_rejects_non_certificates(self):
with pytest.raises(TypeError):
Store(["not a cert"]) # type: ignore[list-item]
class TestServerVerifier:
@pytest.mark.parametrize(
("validation_time", "valid"),
[
# 03:15:02 UTC+2, or 1 second before expiry in UTC
("2018-11-16T03:15:02+02:00", True),
# 00:15:04 UTC-1, or 1 second after expiry in UTC
("2018-11-16T00:15:04-01:00", False),
],
)
def test_verify_tz_aware(self, validation_time, valid):
# expires 2018-11-16 01:15:03 UTC
leaf = _load_cert(
os.path.join("x509", "cryptography.io.pem"),
x509.load_pem_x509_certificate,
)
store = Store([leaf])
builder = PolicyBuilder().store(store)
builder = builder.time(
datetime.datetime.fromisoformat(validation_time)
)
verifier = builder.build_server_verifier(DNSName("cryptography.io"))
if valid:
assert verifier.verify(leaf, []) == [leaf]
else:
with pytest.raises(
x509.verification.VerificationError,
match="cert is not valid at validation time",
):
verifier.verify(leaf, [])