general_name.py 7.8 KB

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