Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/x509/general_name.py: 43%
166 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 07:26 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 07:26 +0000
1# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
5from __future__ import annotations
7import abc
8import ipaddress
9import typing
10from email.utils import parseaddr
12from cryptography.x509.name import Name
13from cryptography.x509.oid import ObjectIdentifier
15_IPAddressTypes = typing.Union[
16 ipaddress.IPv4Address,
17 ipaddress.IPv6Address,
18 ipaddress.IPv4Network,
19 ipaddress.IPv6Network,
20]
23class UnsupportedGeneralNameType(Exception):
24 pass
27class GeneralName(metaclass=abc.ABCMeta):
28 @property
29 @abc.abstractmethod
30 def value(self) -> typing.Any:
31 """
32 Return the value of the object
33 """
36class RFC822Name(GeneralName):
37 def __init__(self, value: str) -> None:
38 if isinstance(value, str):
39 try:
40 value.encode("ascii")
41 except UnicodeEncodeError:
42 raise ValueError(
43 "RFC822Name values should be passed as an A-label string. "
44 "This means unicode characters should be encoded via "
45 "a library like idna."
46 )
47 else:
48 raise TypeError("value must be string")
50 name, address = parseaddr(value)
51 if name or not address:
52 # parseaddr has found a name (e.g. Name <email>) or the entire
53 # value is an empty string.
54 raise ValueError("Invalid rfc822name value")
56 self._value = value
58 @property
59 def value(self) -> str:
60 return self._value
62 @classmethod
63 def _init_without_validation(cls, value: str) -> RFC822Name:
64 instance = cls.__new__(cls)
65 instance._value = value
66 return instance
68 def __repr__(self) -> str:
69 return f"<RFC822Name(value={self.value!r})>"
71 def __eq__(self, other: object) -> bool:
72 if not isinstance(other, RFC822Name):
73 return NotImplemented
75 return self.value == other.value
77 def __hash__(self) -> int:
78 return hash(self.value)
81class DNSName(GeneralName):
82 def __init__(self, value: str) -> None:
83 if isinstance(value, str):
84 try:
85 value.encode("ascii")
86 except UnicodeEncodeError:
87 raise ValueError(
88 "DNSName values should be passed as an A-label string. "
89 "This means unicode characters should be encoded via "
90 "a library like idna."
91 )
92 else:
93 raise TypeError("value must be string")
95 self._value = value
97 @property
98 def value(self) -> str:
99 return self._value
101 @classmethod
102 def _init_without_validation(cls, value: str) -> DNSName:
103 instance = cls.__new__(cls)
104 instance._value = value
105 return instance
107 def __repr__(self) -> str:
108 return f"<DNSName(value={self.value!r})>"
110 def __eq__(self, other: object) -> bool:
111 if not isinstance(other, DNSName):
112 return NotImplemented
114 return self.value == other.value
116 def __hash__(self) -> int:
117 return hash(self.value)
120class UniformResourceIdentifier(GeneralName):
121 def __init__(self, value: str) -> None:
122 if isinstance(value, str):
123 try:
124 value.encode("ascii")
125 except UnicodeEncodeError:
126 raise ValueError(
127 "URI values should be passed as an A-label string. "
128 "This means unicode characters should be encoded via "
129 "a library like idna."
130 )
131 else:
132 raise TypeError("value must be string")
134 self._value = value
136 @property
137 def value(self) -> str:
138 return self._value
140 @classmethod
141 def _init_without_validation(cls, value: str) -> UniformResourceIdentifier:
142 instance = cls.__new__(cls)
143 instance._value = value
144 return instance
146 def __repr__(self) -> str:
147 return f"<UniformResourceIdentifier(value={self.value!r})>"
149 def __eq__(self, other: object) -> bool:
150 if not isinstance(other, UniformResourceIdentifier):
151 return NotImplemented
153 return self.value == other.value
155 def __hash__(self) -> int:
156 return hash(self.value)
159class DirectoryName(GeneralName):
160 def __init__(self, value: Name) -> None:
161 if not isinstance(value, Name):
162 raise TypeError("value must be a Name")
164 self._value = value
166 @property
167 def value(self) -> Name:
168 return self._value
170 def __repr__(self) -> str:
171 return f"<DirectoryName(value={self.value})>"
173 def __eq__(self, other: object) -> bool:
174 if not isinstance(other, DirectoryName):
175 return NotImplemented
177 return self.value == other.value
179 def __hash__(self) -> int:
180 return hash(self.value)
183class RegisteredID(GeneralName):
184 def __init__(self, value: ObjectIdentifier) -> None:
185 if not isinstance(value, ObjectIdentifier):
186 raise TypeError("value must be an ObjectIdentifier")
188 self._value = value
190 @property
191 def value(self) -> ObjectIdentifier:
192 return self._value
194 def __repr__(self) -> str:
195 return f"<RegisteredID(value={self.value})>"
197 def __eq__(self, other: object) -> bool:
198 if not isinstance(other, RegisteredID):
199 return NotImplemented
201 return self.value == other.value
203 def __hash__(self) -> int:
204 return hash(self.value)
207class IPAddress(GeneralName):
208 def __init__(self, value: _IPAddressTypes) -> None:
209 if not isinstance(
210 value,
211 (
212 ipaddress.IPv4Address,
213 ipaddress.IPv6Address,
214 ipaddress.IPv4Network,
215 ipaddress.IPv6Network,
216 ),
217 ):
218 raise TypeError(
219 "value must be an instance of ipaddress.IPv4Address, "
220 "ipaddress.IPv6Address, ipaddress.IPv4Network, or "
221 "ipaddress.IPv6Network"
222 )
224 self._value = value
226 @property
227 def value(self) -> _IPAddressTypes:
228 return self._value
230 def _packed(self) -> bytes:
231 if isinstance(
232 self.value, (ipaddress.IPv4Address, ipaddress.IPv6Address)
233 ):
234 return self.value.packed
235 else:
236 return (
237 self.value.network_address.packed + self.value.netmask.packed
238 )
240 def __repr__(self) -> str:
241 return f"<IPAddress(value={self.value})>"
243 def __eq__(self, other: object) -> bool:
244 if not isinstance(other, IPAddress):
245 return NotImplemented
247 return self.value == other.value
249 def __hash__(self) -> int:
250 return hash(self.value)
253class OtherName(GeneralName):
254 def __init__(self, type_id: ObjectIdentifier, value: bytes) -> None:
255 if not isinstance(type_id, ObjectIdentifier):
256 raise TypeError("type_id must be an ObjectIdentifier")
257 if not isinstance(value, bytes):
258 raise TypeError("value must be a binary string")
260 self._type_id = type_id
261 self._value = value
263 @property
264 def type_id(self) -> ObjectIdentifier:
265 return self._type_id
267 @property
268 def value(self) -> bytes:
269 return self._value
271 def __repr__(self) -> str:
272 return f"<OtherName(type_id={self.type_id}, value={self.value!r})>"
274 def __eq__(self, other: object) -> bool:
275 if not isinstance(other, OtherName):
276 return NotImplemented
278 return self.type_id == other.type_id and self.value == other.value
280 def __hash__(self) -> int:
281 return hash((self.type_id, self.value))