Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

general_name.py 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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.
  4. from __future__ import annotations
  5. import abc
  6. import ipaddress
  7. import typing
  8. from email.utils import parseaddr
  9. from cryptography.x509.name import Name
  10. from cryptography.x509.oid import ObjectIdentifier
  11. _IPAddressTypes = typing.Union[
  12. ipaddress.IPv4Address,
  13. ipaddress.IPv6Address,
  14. ipaddress.IPv4Network,
  15. ipaddress.IPv6Network,
  16. ]
  17. class UnsupportedGeneralNameType(Exception):
  18. pass
  19. class GeneralName(metaclass=abc.ABCMeta):
  20. @property
  21. @abc.abstractmethod
  22. def value(self) -> typing.Any:
  23. """
  24. Return the value of the object
  25. """
  26. class RFC822Name(GeneralName):
  27. def __init__(self, value: str) -> None:
  28. if isinstance(value, str):
  29. try:
  30. value.encode("ascii")
  31. except UnicodeEncodeError:
  32. raise ValueError(
  33. "RFC822Name values should be passed as an A-label string. "
  34. "This means unicode characters should be encoded via "
  35. "a library like idna."
  36. )
  37. else:
  38. raise TypeError("value must be string")
  39. name, address = parseaddr(value)
  40. if name or not address:
  41. # parseaddr has found a name (e.g. Name <email>) or the entire
  42. # value is an empty string.
  43. raise ValueError("Invalid rfc822name value")
  44. self._value = value
  45. @property
  46. def value(self) -> str:
  47. return self._value
  48. @classmethod
  49. def _init_without_validation(cls, value: str) -> RFC822Name:
  50. instance = cls.__new__(cls)
  51. instance._value = value
  52. return instance
  53. def __repr__(self) -> str:
  54. return f"<RFC822Name(value={self.value!r})>"
  55. def __eq__(self, other: object) -> bool:
  56. if not isinstance(other, RFC822Name):
  57. return NotImplemented
  58. return self.value == other.value
  59. def __hash__(self) -> int:
  60. return hash(self.value)
  61. class DNSName(GeneralName):
  62. def __init__(self, value: str) -> None:
  63. if isinstance(value, str):
  64. try:
  65. value.encode("ascii")
  66. except UnicodeEncodeError:
  67. raise ValueError(
  68. "DNSName values should be passed as an A-label string. "
  69. "This means unicode characters should be encoded via "
  70. "a library like idna."
  71. )
  72. else:
  73. raise TypeError("value must be string")
  74. self._value = value
  75. @property
  76. def value(self) -> str:
  77. return self._value
  78. @classmethod
  79. def _init_without_validation(cls, value: str) -> DNSName:
  80. instance = cls.__new__(cls)
  81. instance._value = value
  82. return instance
  83. def __repr__(self) -> str:
  84. return f"<DNSName(value={self.value!r})>"
  85. def __eq__(self, other: object) -> bool:
  86. if not isinstance(other, DNSName):
  87. return NotImplemented
  88. return self.value == other.value
  89. def __hash__(self) -> int:
  90. return hash(self.value)
  91. class UniformResourceIdentifier(GeneralName):
  92. def __init__(self, value: str) -> None:
  93. if isinstance(value, str):
  94. try:
  95. value.encode("ascii")
  96. except UnicodeEncodeError:
  97. raise ValueError(
  98. "URI values should be passed as an A-label string. "
  99. "This means unicode characters should be encoded via "
  100. "a library like idna."
  101. )
  102. else:
  103. raise TypeError("value must be string")
  104. self._value = value
  105. @property
  106. def value(self) -> str:
  107. return self._value
  108. @classmethod
  109. def _init_without_validation(cls, value: str) -> UniformResourceIdentifier:
  110. instance = cls.__new__(cls)
  111. instance._value = value
  112. return instance
  113. def __repr__(self) -> str:
  114. return f"<UniformResourceIdentifier(value={self.value!r})>"
  115. def __eq__(self, other: object) -> bool:
  116. if not isinstance(other, UniformResourceIdentifier):
  117. return NotImplemented
  118. return self.value == other.value
  119. def __hash__(self) -> int:
  120. return hash(self.value)
  121. class DirectoryName(GeneralName):
  122. def __init__(self, value: Name) -> None:
  123. if not isinstance(value, Name):
  124. raise TypeError("value must be a Name")
  125. self._value = value
  126. @property
  127. def value(self) -> Name:
  128. return self._value
  129. def __repr__(self) -> str:
  130. return f"<DirectoryName(value={self.value})>"
  131. def __eq__(self, other: object) -> bool:
  132. if not isinstance(other, DirectoryName):
  133. return NotImplemented
  134. return self.value == other.value
  135. def __hash__(self) -> int:
  136. return hash(self.value)
  137. class RegisteredID(GeneralName):
  138. def __init__(self, value: ObjectIdentifier) -> None:
  139. if not isinstance(value, ObjectIdentifier):
  140. raise TypeError("value must be an ObjectIdentifier")
  141. self._value = value
  142. @property
  143. def value(self) -> ObjectIdentifier:
  144. return self._value
  145. def __repr__(self) -> str:
  146. return f"<RegisteredID(value={self.value})>"
  147. def __eq__(self, other: object) -> bool:
  148. if not isinstance(other, RegisteredID):
  149. return NotImplemented
  150. return self.value == other.value
  151. def __hash__(self) -> int:
  152. return hash(self.value)
  153. class IPAddress(GeneralName):
  154. def __init__(self, value: _IPAddressTypes) -> None:
  155. if not isinstance(
  156. value,
  157. (
  158. ipaddress.IPv4Address,
  159. ipaddress.IPv6Address,
  160. ipaddress.IPv4Network,
  161. ipaddress.IPv6Network,
  162. ),
  163. ):
  164. raise TypeError(
  165. "value must be an instance of ipaddress.IPv4Address, "
  166. "ipaddress.IPv6Address, ipaddress.IPv4Network, or "
  167. "ipaddress.IPv6Network"
  168. )
  169. self._value = value
  170. @property
  171. def value(self) -> _IPAddressTypes:
  172. return self._value
  173. def _packed(self) -> bytes:
  174. if isinstance(
  175. self.value, (ipaddress.IPv4Address, ipaddress.IPv6Address)
  176. ):
  177. return self.value.packed
  178. else:
  179. return (
  180. self.value.network_address.packed + self.value.netmask.packed
  181. )
  182. def __repr__(self) -> str:
  183. return f"<IPAddress(value={self.value})>"
  184. def __eq__(self, other: object) -> bool:
  185. if not isinstance(other, IPAddress):
  186. return NotImplemented
  187. return self.value == other.value
  188. def __hash__(self) -> int:
  189. return hash(self.value)
  190. class OtherName(GeneralName):
  191. def __init__(self, type_id: ObjectIdentifier, value: bytes) -> None:
  192. if not isinstance(type_id, ObjectIdentifier):
  193. raise TypeError("type_id must be an ObjectIdentifier")
  194. if not isinstance(value, bytes):
  195. raise TypeError("value must be a binary string")
  196. self._type_id = type_id
  197. self._value = value
  198. @property
  199. def type_id(self) -> ObjectIdentifier:
  200. return self._type_id
  201. @property
  202. def value(self) -> bytes:
  203. return self._value
  204. def __repr__(self) -> str:
  205. return "<OtherName(type_id={}, value={!r})>".format(
  206. self.type_id, self.value
  207. )
  208. def __eq__(self, other: object) -> bool:
  209. if not isinstance(other, OtherName):
  210. return NotImplemented
  211. return self.type_id == other.type_id and self.value == other.value
  212. def __hash__(self) -> int:
  213. return hash((self.type_id, self.value))