asn1.py 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064
  1. # -*- coding: ascii -*-
  2. #
  3. # Util/asn1.py : Minimal support for ASN.1 DER binary encoding.
  4. #
  5. # ===================================================================
  6. # The contents of this file are dedicated to the public domain. To
  7. # the extent that dedication to the public domain is not available,
  8. # everyone is granted a worldwide, perpetual, royalty-free,
  9. # non-exclusive license to exercise all rights associated with the
  10. # contents of this file for any purpose whatsoever.
  11. # No rights are reserved.
  12. #
  13. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  17. # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  18. # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. # SOFTWARE.
  21. # ===================================================================
  22. import struct
  23. from Crypto.Util.py3compat import byte_string, bchr, bord
  24. from Crypto.Util.number import long_to_bytes, bytes_to_long
  25. __all__ = ['DerObject', 'DerInteger', 'DerBoolean', 'DerOctetString',
  26. 'DerNull', 'DerSequence', 'DerObjectId', 'DerBitString', 'DerSetOf']
  27. # Useful references:
  28. # - https://luca.ntop.org/Teaching/Appunti/asn1.html
  29. # - https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/
  30. # - https://www.zytrax.com/tech/survival/asn1.html
  31. # - https://www.oss.com/asn1/resources/books-whitepapers-pubs/larmouth-asn1-book.pdf
  32. # - https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
  33. # - https://misc.daniel-marschall.de/asn.1/oid-converter/online.php
  34. def _is_number(x, only_non_negative=False):
  35. test = 0
  36. try:
  37. test = x + test
  38. except TypeError:
  39. return False
  40. return not only_non_negative or x >= 0
  41. class BytesIO_EOF(object):
  42. """This class differs from BytesIO in that a ValueError exception is
  43. raised whenever EOF is reached."""
  44. def __init__(self, initial_bytes):
  45. self._buffer = initial_bytes
  46. self._index = 0
  47. self._bookmark = None
  48. def set_bookmark(self):
  49. self._bookmark = self._index
  50. def data_since_bookmark(self):
  51. assert self._bookmark is not None
  52. return self._buffer[self._bookmark:self._index]
  53. def remaining_data(self):
  54. return len(self._buffer) - self._index
  55. def read(self, length):
  56. new_index = self._index + length
  57. if new_index > len(self._buffer):
  58. raise ValueError("Not enough data for DER decoding: expected %d bytes and found %d" % (new_index, len(self._buffer)))
  59. result = self._buffer[self._index:new_index]
  60. self._index = new_index
  61. return result
  62. def read_byte(self):
  63. return bord(self.read(1)[0])
  64. class DerObject(object):
  65. """Base class for defining a single DER object.
  66. This class should never be directly instantiated.
  67. """
  68. def __init__(self, asn1Id=None, payload=b'', implicit=None,
  69. constructed=False, explicit=None):
  70. """Initialize the DER object according to a specific ASN.1 type.
  71. :Parameters:
  72. asn1Id : integer or byte
  73. The universal DER tag number for this object
  74. (e.g. 0x10 for a SEQUENCE).
  75. If None, the tag is not known yet.
  76. payload : byte string
  77. The initial payload of the object (that it,
  78. the content octets).
  79. If not specified, the payload is empty.
  80. implicit : integer or byte
  81. The IMPLICIT tag number (< 0x1F) to use for the encoded object.
  82. It overrides the universal tag *asn1Id*.
  83. It cannot be combined with the ``explicit`` parameter.
  84. By default, there is no IMPLICIT tag.
  85. constructed : bool
  86. True when the ASN.1 type is *constructed*.
  87. False when it is *primitive* (default).
  88. explicit : integer or byte
  89. The EXPLICIT tag number (< 0x1F) to use for the encoded object.
  90. It cannot be combined with the ``implicit`` parameter.
  91. By default, there is no EXPLICIT tag.
  92. """
  93. if asn1Id is None:
  94. # The tag octet will be read in with ``decode``
  95. self._tag_octet = None
  96. return
  97. asn1Id = self._convertTag(asn1Id)
  98. self.payload = payload
  99. # In a BER/DER identifier octet:
  100. # * bits 4-0 contain the tag value
  101. # * bit 5 is set if the type is 'constructed'
  102. # and unset if 'primitive'
  103. # * bits 7-6 depend on the encoding class
  104. #
  105. # Class | Bit 7, Bit 6
  106. # ----------------------------------
  107. # universal | 0 0
  108. # application | 0 1
  109. # context-spec | 1 0 (default for IMPLICIT/EXPLICIT)
  110. # private | 1 1
  111. #
  112. constructed_bit = 0x20 if constructed else 0x00
  113. if None not in (explicit, implicit):
  114. raise ValueError("Explicit and implicit tags are"
  115. " mutually exclusive")
  116. if implicit is not None:
  117. # IMPLICIT tag overrides asn1Id
  118. self._tag_octet = 0x80 | constructed_bit | self._convertTag(implicit)
  119. elif explicit is not None:
  120. # 'constructed bit' is always asserted for an EXPLICIT tag
  121. self._tag_octet = 0x80 | 0x20 | self._convertTag(explicit)
  122. self._inner_tag_octet = constructed_bit | asn1Id
  123. else:
  124. # Neither IMPLICIT nor EXPLICIT
  125. self._tag_octet = constructed_bit | asn1Id
  126. def _convertTag(self, tag):
  127. """Check if *tag* is a real DER tag (5 bits).
  128. Convert it from a character to number if necessary.
  129. """
  130. if not _is_number(tag):
  131. if len(tag) == 1:
  132. tag = bord(tag[0])
  133. # Ensure that tag is a low tag
  134. if not (_is_number(tag) and 0 <= tag < 0x1F):
  135. raise ValueError("Wrong DER tag")
  136. return tag
  137. @staticmethod
  138. def _definite_form(length):
  139. """Build length octets according to BER/DER
  140. definite form.
  141. """
  142. if length > 127:
  143. encoding = long_to_bytes(length)
  144. return bchr(len(encoding) + 128) + encoding
  145. return bchr(length)
  146. def encode(self):
  147. """Return this DER element, fully encoded as a binary byte string."""
  148. # Concatenate identifier octets, length octets,
  149. # and contents octets
  150. output_payload = self.payload
  151. # In case of an EXTERNAL tag, first encode the inner
  152. # element.
  153. if hasattr(self, "_inner_tag_octet"):
  154. output_payload = (bchr(self._inner_tag_octet) +
  155. self._definite_form(len(self.payload)) +
  156. self.payload)
  157. return (bchr(self._tag_octet) +
  158. self._definite_form(len(output_payload)) +
  159. output_payload)
  160. def _decodeLen(self, s):
  161. """Decode DER length octets from a file."""
  162. length = s.read_byte()
  163. if length > 127:
  164. encoded_length = s.read(length & 0x7F)
  165. if bord(encoded_length[0]) == 0:
  166. raise ValueError("Invalid DER: length has leading zero")
  167. length = bytes_to_long(encoded_length)
  168. if length <= 127:
  169. raise ValueError("Invalid DER: length in long form but smaller than 128")
  170. return length
  171. def decode(self, der_encoded, strict=False):
  172. """Decode a complete DER element, and re-initializes this
  173. object with it.
  174. Args:
  175. der_encoded (byte string): A complete DER element.
  176. Raises:
  177. ValueError: in case of parsing errors.
  178. """
  179. if not byte_string(der_encoded):
  180. raise ValueError("Input is not a byte string")
  181. s = BytesIO_EOF(der_encoded)
  182. self._decodeFromStream(s, strict)
  183. # There shouldn't be other bytes left
  184. if s.remaining_data() > 0:
  185. raise ValueError("Unexpected extra data after the DER structure")
  186. return self
  187. def _decodeFromStream(self, s, strict):
  188. """Decode a complete DER element from a file."""
  189. idOctet = s.read_byte()
  190. if self._tag_octet is not None:
  191. if idOctet != self._tag_octet:
  192. raise ValueError("Unexpected DER tag")
  193. else:
  194. self._tag_octet = idOctet
  195. length = self._decodeLen(s)
  196. self.payload = s.read(length)
  197. # In case of an EXTERNAL tag, further decode the inner
  198. # element.
  199. if hasattr(self, "_inner_tag_octet"):
  200. p = BytesIO_EOF(self.payload)
  201. inner_octet = p.read_byte()
  202. if inner_octet != self._inner_tag_octet:
  203. raise ValueError("Unexpected internal DER tag")
  204. length = self._decodeLen(p)
  205. self.payload = p.read(length)
  206. # There shouldn't be other bytes left
  207. if p.remaining_data() > 0:
  208. raise ValueError("Unexpected extra data after the DER structure")
  209. class DerInteger(DerObject):
  210. """Class to model a DER INTEGER.
  211. An example of encoding is::
  212. >>> from Crypto.Util.asn1 import DerInteger
  213. >>> from binascii import hexlify, unhexlify
  214. >>> int_der = DerInteger(9)
  215. >>> print hexlify(int_der.encode())
  216. which will show ``020109``, the DER encoding of 9.
  217. And for decoding::
  218. >>> s = unhexlify(b'020109')
  219. >>> try:
  220. >>> int_der = DerInteger()
  221. >>> int_der.decode(s)
  222. >>> print int_der.value
  223. >>> except ValueError:
  224. >>> print "Not a valid DER INTEGER"
  225. the output will be ``9``.
  226. :ivar value: The integer value
  227. :vartype value: integer
  228. """
  229. def __init__(self, value=0, implicit=None, explicit=None):
  230. """Initialize the DER object as an INTEGER.
  231. :Parameters:
  232. value : integer
  233. The value of the integer.
  234. implicit : integer
  235. The IMPLICIT tag to use for the encoded object.
  236. It overrides the universal tag for INTEGER (2).
  237. """
  238. DerObject.__init__(self, 0x02, b'', implicit,
  239. False, explicit)
  240. self.value = value # The integer value
  241. def encode(self):
  242. """Return the DER INTEGER, fully encoded as a
  243. binary string."""
  244. number = self.value
  245. self.payload = b''
  246. while True:
  247. self.payload = bchr(int(number & 255)) + self.payload
  248. if 128 <= number <= 255:
  249. self.payload = bchr(0x00) + self.payload
  250. if -128 <= number <= 255:
  251. break
  252. number >>= 8
  253. return DerObject.encode(self)
  254. def decode(self, der_encoded, strict=False):
  255. """Decode a DER-encoded INTEGER, and re-initializes this
  256. object with it.
  257. Args:
  258. der_encoded (byte string): A complete INTEGER DER element.
  259. Raises:
  260. ValueError: in case of parsing errors.
  261. """
  262. return DerObject.decode(self, der_encoded, strict=strict)
  263. def _decodeFromStream(self, s, strict):
  264. """Decode a complete DER INTEGER from a file."""
  265. # Fill up self.payload
  266. DerObject._decodeFromStream(self, s, strict)
  267. if strict:
  268. if len(self.payload) == 0:
  269. raise ValueError("Invalid encoding for DER INTEGER: empty payload")
  270. if len(self.payload) >= 2 and struct.unpack('>H', self.payload[:2])[0] < 0x80:
  271. raise ValueError("Invalid encoding for DER INTEGER: leading zero")
  272. # Derive self.value from self.payload
  273. self.value = 0
  274. bits = 1
  275. for i in self.payload:
  276. self.value *= 256
  277. self.value += bord(i)
  278. bits <<= 8
  279. if self.payload and bord(self.payload[0]) & 0x80:
  280. self.value -= bits
  281. class DerBoolean(DerObject):
  282. """Class to model a DER-encoded BOOLEAN.
  283. An example of encoding is::
  284. >>> from Crypto.Util.asn1 import DerBoolean
  285. >>> bool_der = DerBoolean(True)
  286. >>> print(bool_der.encode().hex())
  287. which will show ``0101ff``, the DER encoding of True.
  288. And for decoding::
  289. >>> s = bytes.fromhex('0101ff')
  290. >>> try:
  291. >>> bool_der = DerBoolean()
  292. >>> bool_der.decode(s)
  293. >>> print(bool_der.value)
  294. >>> except ValueError:
  295. >>> print "Not a valid DER BOOLEAN"
  296. the output will be ``True``.
  297. :ivar value: The boolean value
  298. :vartype value: boolean
  299. """
  300. def __init__(self, value=False, implicit=None, explicit=None):
  301. """Initialize the DER object as a BOOLEAN.
  302. Args:
  303. value (boolean):
  304. The value of the boolean. Default is False.
  305. implicit (integer or byte):
  306. The IMPLICIT tag number (< 0x1F) to use for the encoded object.
  307. It overrides the universal tag for BOOLEAN (1).
  308. It cannot be combined with the ``explicit`` parameter.
  309. By default, there is no IMPLICIT tag.
  310. explicit (integer or byte):
  311. The EXPLICIT tag number (< 0x1F) to use for the encoded object.
  312. It cannot be combined with the ``implicit`` parameter.
  313. By default, there is no EXPLICIT tag.
  314. """
  315. DerObject.__init__(self, 0x01, b'', implicit, False, explicit)
  316. self.value = value # The boolean value
  317. def encode(self):
  318. """Return the DER BOOLEAN, fully encoded as a binary string."""
  319. self.payload = b'\xFF' if self.value else b'\x00'
  320. return DerObject.encode(self)
  321. def decode(self, der_encoded, strict=False):
  322. """Decode a DER-encoded BOOLEAN, and re-initializes this object with it.
  323. Args:
  324. der_encoded (byte string): A DER-encoded BOOLEAN.
  325. Raises:
  326. ValueError: in case of parsing errors.
  327. """
  328. return DerObject.decode(self, der_encoded, strict)
  329. def _decodeFromStream(self, s, strict):
  330. """Decode a DER-encoded BOOLEAN from a file."""
  331. # Fill up self.payload
  332. DerObject._decodeFromStream(self, s, strict)
  333. if len(self.payload) != 1:
  334. raise ValueError("Invalid encoding for DER BOOLEAN: payload is not 1 byte")
  335. if bord(self.payload[0]) == 0:
  336. self.value = False
  337. elif bord(self.payload[0]) == 0xFF:
  338. self.value = True
  339. else:
  340. raise ValueError("Invalid payload for DER BOOLEAN")
  341. class DerSequence(DerObject):
  342. """Class to model a DER SEQUENCE.
  343. This object behaves like a dynamic Python sequence.
  344. Sub-elements that are INTEGERs behave like Python integers.
  345. Any other sub-element is a binary string encoded as a complete DER
  346. sub-element (TLV).
  347. An example of encoding is:
  348. >>> from Crypto.Util.asn1 import DerSequence, DerInteger
  349. >>> from binascii import hexlify, unhexlify
  350. >>> obj_der = unhexlify('070102')
  351. >>> seq_der = DerSequence([4])
  352. >>> seq_der.append(9)
  353. >>> seq_der.append(obj_der.encode())
  354. >>> print hexlify(seq_der.encode())
  355. which will show ``3009020104020109070102``, the DER encoding of the
  356. sequence containing ``4``, ``9``, and the object with payload ``02``.
  357. For decoding:
  358. >>> s = unhexlify(b'3009020104020109070102')
  359. >>> try:
  360. >>> seq_der = DerSequence()
  361. >>> seq_der.decode(s)
  362. >>> print len(seq_der)
  363. >>> print seq_der[0]
  364. >>> print seq_der[:]
  365. >>> except ValueError:
  366. >>> print "Not a valid DER SEQUENCE"
  367. the output will be::
  368. 3
  369. 4
  370. [4, 9, b'\x07\x01\x02']
  371. """
  372. def __init__(self, startSeq=None, implicit=None, explicit=None):
  373. """Initialize the DER object as a SEQUENCE.
  374. :Parameters:
  375. startSeq : Python sequence
  376. A sequence whose element are either integers or
  377. other DER objects.
  378. implicit : integer or byte
  379. The IMPLICIT tag number (< 0x1F) to use for the encoded object.
  380. It overrides the universal tag for SEQUENCE (16).
  381. It cannot be combined with the ``explicit`` parameter.
  382. By default, there is no IMPLICIT tag.
  383. explicit : integer or byte
  384. The EXPLICIT tag number (< 0x1F) to use for the encoded object.
  385. It cannot be combined with the ``implicit`` parameter.
  386. By default, there is no EXPLICIT tag.
  387. """
  388. DerObject.__init__(self, 0x10, b'', implicit, True, explicit)
  389. if startSeq is None:
  390. self._seq = []
  391. else:
  392. self._seq = startSeq
  393. # A few methods to make it behave like a python sequence
  394. def __delitem__(self, n):
  395. del self._seq[n]
  396. def __getitem__(self, n):
  397. return self._seq[n]
  398. def __setitem__(self, key, value):
  399. self._seq[key] = value
  400. def __setslice__(self, i, j, sequence):
  401. self._seq[i:j] = sequence
  402. def __delslice__(self, i, j):
  403. del self._seq[i:j]
  404. def __getslice__(self, i, j):
  405. return self._seq[max(0, i):max(0, j)]
  406. def __len__(self):
  407. return len(self._seq)
  408. def __iadd__(self, item):
  409. self._seq.append(item)
  410. return self
  411. def append(self, item):
  412. self._seq.append(item)
  413. return self
  414. def insert(self, index, item):
  415. self._seq.insert(index, item)
  416. return self
  417. def hasInts(self, only_non_negative=True):
  418. """Return the number of items in this sequence that are
  419. integers.
  420. Args:
  421. only_non_negative (boolean):
  422. If ``True``, negative integers are not counted in.
  423. """
  424. items = [x for x in self._seq if _is_number(x, only_non_negative)]
  425. return len(items)
  426. def hasOnlyInts(self, only_non_negative=True):
  427. """Return ``True`` if all items in this sequence are integers
  428. or non-negative integers.
  429. This function returns False is the sequence is empty,
  430. or at least one member is not an integer.
  431. Args:
  432. only_non_negative (boolean):
  433. If ``True``, the presence of negative integers
  434. causes the method to return ``False``."""
  435. return self._seq and self.hasInts(only_non_negative) == len(self._seq)
  436. def encode(self):
  437. """Return this DER SEQUENCE, fully encoded as a
  438. binary string.
  439. Raises:
  440. ValueError: if some elements in the sequence are neither integers
  441. nor byte strings.
  442. """
  443. self.payload = b''
  444. for item in self._seq:
  445. if byte_string(item):
  446. self.payload += item
  447. elif _is_number(item):
  448. self.payload += DerInteger(item).encode()
  449. else:
  450. self.payload += item.encode()
  451. return DerObject.encode(self)
  452. def decode(self, der_encoded, strict=False, nr_elements=None, only_ints_expected=False):
  453. """Decode a complete DER SEQUENCE, and re-initializes this
  454. object with it.
  455. Args:
  456. der_encoded (byte string):
  457. A complete SEQUENCE DER element.
  458. nr_elements (None or integer or list of integers):
  459. The number of members the SEQUENCE can have
  460. only_ints_expected (boolean):
  461. Whether the SEQUENCE is expected to contain only integers.
  462. strict (boolean):
  463. Whether decoding must check for strict DER compliancy.
  464. Raises:
  465. ValueError: in case of parsing errors.
  466. DER INTEGERs are decoded into Python integers. Any other DER
  467. element is not decoded. Its validity is not checked.
  468. """
  469. self._nr_elements = nr_elements
  470. result = DerObject.decode(self, der_encoded, strict=strict)
  471. if only_ints_expected and not self.hasOnlyInts():
  472. raise ValueError("Some members are not INTEGERs")
  473. return result
  474. def _decodeFromStream(self, s, strict):
  475. """Decode a complete DER SEQUENCE from a file."""
  476. self._seq = []
  477. # Fill up self.payload
  478. DerObject._decodeFromStream(self, s, strict)
  479. # Add one item at a time to self.seq, by scanning self.payload
  480. p = BytesIO_EOF(self.payload)
  481. while p.remaining_data() > 0:
  482. p.set_bookmark()
  483. der = DerObject()
  484. der._decodeFromStream(p, strict)
  485. # Parse INTEGERs differently
  486. if der._tag_octet != 0x02:
  487. self._seq.append(p.data_since_bookmark())
  488. else:
  489. derInt = DerInteger()
  490. data = p.data_since_bookmark()
  491. derInt.decode(data, strict=strict)
  492. self._seq.append(derInt.value)
  493. ok = True
  494. if self._nr_elements is not None:
  495. try:
  496. ok = len(self._seq) in self._nr_elements
  497. except TypeError:
  498. ok = len(self._seq) == self._nr_elements
  499. if not ok:
  500. raise ValueError("Unexpected number of members (%d)"
  501. " in the sequence" % len(self._seq))
  502. class DerOctetString(DerObject):
  503. """Class to model a DER OCTET STRING.
  504. An example of encoding is:
  505. >>> from Crypto.Util.asn1 import DerOctetString
  506. >>> from binascii import hexlify, unhexlify
  507. >>> os_der = DerOctetString(b'\\xaa')
  508. >>> os_der.payload += b'\\xbb'
  509. >>> print hexlify(os_der.encode())
  510. which will show ``0402aabb``, the DER encoding for the byte string
  511. ``b'\\xAA\\xBB'``.
  512. For decoding:
  513. >>> s = unhexlify(b'0402aabb')
  514. >>> try:
  515. >>> os_der = DerOctetString()
  516. >>> os_der.decode(s)
  517. >>> print hexlify(os_der.payload)
  518. >>> except ValueError:
  519. >>> print "Not a valid DER OCTET STRING"
  520. the output will be ``aabb``.
  521. :ivar payload: The content of the string
  522. :vartype payload: byte string
  523. """
  524. def __init__(self, value=b'', implicit=None):
  525. """Initialize the DER object as an OCTET STRING.
  526. :Parameters:
  527. value : byte string
  528. The initial payload of the object.
  529. If not specified, the payload is empty.
  530. implicit : integer
  531. The IMPLICIT tag to use for the encoded object.
  532. It overrides the universal tag for OCTET STRING (4).
  533. """
  534. DerObject.__init__(self, 0x04, value, implicit, False)
  535. class DerNull(DerObject):
  536. """Class to model a DER NULL element."""
  537. def __init__(self):
  538. """Initialize the DER object as a NULL."""
  539. DerObject.__init__(self, 0x05, b'', None, False)
  540. class DerObjectId(DerObject):
  541. """Class to model a DER OBJECT ID.
  542. An example of encoding is:
  543. >>> from Crypto.Util.asn1 import DerObjectId
  544. >>> from binascii import hexlify, unhexlify
  545. >>> oid_der = DerObjectId("1.2")
  546. >>> oid_der.value += ".840.113549.1.1.1"
  547. >>> print hexlify(oid_der.encode())
  548. which will show ``06092a864886f70d010101``, the DER encoding for the
  549. RSA Object Identifier ``1.2.840.113549.1.1.1``.
  550. For decoding:
  551. >>> s = unhexlify(b'06092a864886f70d010101')
  552. >>> try:
  553. >>> oid_der = DerObjectId()
  554. >>> oid_der.decode(s)
  555. >>> print oid_der.value
  556. >>> except ValueError:
  557. >>> print "Not a valid DER OBJECT ID"
  558. the output will be ``1.2.840.113549.1.1.1``.
  559. :ivar value: The Object ID (OID), a dot separated list of integers
  560. :vartype value: string
  561. """
  562. def __init__(self, value='', implicit=None, explicit=None):
  563. """Initialize the DER object as an OBJECT ID.
  564. :Parameters:
  565. value : string
  566. The initial Object Identifier (e.g. "1.2.0.0.6.2").
  567. implicit : integer
  568. The IMPLICIT tag to use for the encoded object.
  569. It overrides the universal tag for OBJECT ID (6).
  570. explicit : integer
  571. The EXPLICIT tag to use for the encoded object.
  572. """
  573. DerObject.__init__(self, 0x06, b'', implicit, False, explicit)
  574. self.value = value
  575. def encode(self):
  576. """Return the DER OBJECT ID, fully encoded as a
  577. binary string."""
  578. comps = [int(x) for x in self.value.split(".")]
  579. if len(comps) < 2:
  580. raise ValueError("Not a valid Object Identifier string")
  581. if comps[0] > 2:
  582. raise ValueError("First component must be 0, 1 or 2")
  583. if comps[0] < 2 and comps[1] > 39:
  584. raise ValueError("Second component must be 39 at most")
  585. subcomps = [40 * comps[0] + comps[1]] + comps[2:]
  586. encoding = []
  587. for v in reversed(subcomps):
  588. encoding.append(v & 0x7F)
  589. v >>= 7
  590. while v:
  591. encoding.append((v & 0x7F) | 0x80)
  592. v >>= 7
  593. self.payload = b''.join([bchr(x) for x in reversed(encoding)])
  594. return DerObject.encode(self)
  595. def decode(self, der_encoded, strict=False):
  596. """Decode a complete DER OBJECT ID, and re-initializes this
  597. object with it.
  598. Args:
  599. der_encoded (byte string):
  600. A complete DER OBJECT ID.
  601. strict (boolean):
  602. Whether decoding must check for strict DER compliancy.
  603. Raises:
  604. ValueError: in case of parsing errors.
  605. """
  606. return DerObject.decode(self, der_encoded, strict)
  607. def _decodeFromStream(self, s, strict):
  608. """Decode a complete DER OBJECT ID from a file."""
  609. # Fill up self.payload
  610. DerObject._decodeFromStream(self, s, strict)
  611. # Derive self.value from self.payload
  612. p = BytesIO_EOF(self.payload)
  613. subcomps = []
  614. v = 0
  615. while p.remaining_data():
  616. c = p.read_byte()
  617. v = (v << 7) + (c & 0x7F)
  618. if not (c & 0x80):
  619. subcomps.append(v)
  620. v = 0
  621. if len(subcomps) == 0:
  622. raise ValueError("Empty payload")
  623. if subcomps[0] < 40:
  624. subcomps[:1] = [0, subcomps[0]]
  625. elif subcomps[0] < 80:
  626. subcomps[:1] = [1, subcomps[0] - 40]
  627. else:
  628. subcomps[:1] = [2, subcomps[0] - 80]
  629. self.value = ".".join([str(x) for x in subcomps])
  630. class DerBitString(DerObject):
  631. """Class to model a DER BIT STRING.
  632. An example of encoding is:
  633. >>> from Crypto.Util.asn1 import DerBitString
  634. >>> bs_der = DerBitString(b'\\xAA')
  635. >>> bs_der.value += b'\\xBB'
  636. >>> print(bs_der.encode().hex())
  637. which will show ``030300aabb``, the DER encoding for the bit string
  638. ``b'\\xAA\\xBB'``.
  639. For decoding:
  640. >>> s = bytes.fromhex('030300aabb')
  641. >>> try:
  642. >>> bs_der = DerBitString()
  643. >>> bs_der.decode(s)
  644. >>> print(bs_der.value.hex())
  645. >>> except ValueError:
  646. >>> print "Not a valid DER BIT STRING"
  647. the output will be ``aabb``.
  648. :ivar value: The content of the string
  649. :vartype value: byte string
  650. """
  651. def __init__(self, value=b'', implicit=None, explicit=None):
  652. """Initialize the DER object as a BIT STRING.
  653. :Parameters:
  654. value : byte string or DER object
  655. The initial, packed bit string.
  656. If not specified, the bit string is empty.
  657. implicit : integer
  658. The IMPLICIT tag to use for the encoded object.
  659. It overrides the universal tag for BIT STRING (3).
  660. explicit : integer
  661. The EXPLICIT tag to use for the encoded object.
  662. """
  663. DerObject.__init__(self, 0x03, b'', implicit, False, explicit)
  664. # The bitstring value (packed)
  665. if isinstance(value, DerObject):
  666. self.value = value.encode()
  667. else:
  668. self.value = value
  669. def encode(self):
  670. """Return the DER BIT STRING, fully encoded as a
  671. byte string."""
  672. # Add padding count byte
  673. self.payload = b'\x00' + self.value
  674. return DerObject.encode(self)
  675. def decode(self, der_encoded, strict=False):
  676. """Decode a complete DER BIT STRING, and re-initializes this
  677. object with it.
  678. Args:
  679. der_encoded (byte string): a complete DER BIT STRING.
  680. strict (boolean):
  681. Whether decoding must check for strict DER compliancy.
  682. Raises:
  683. ValueError: in case of parsing errors.
  684. """
  685. return DerObject.decode(self, der_encoded, strict)
  686. def _decodeFromStream(self, s, strict):
  687. """Decode a complete DER BIT STRING DER from a file."""
  688. # Fill-up self.payload
  689. DerObject._decodeFromStream(self, s, strict)
  690. if self.payload and bord(self.payload[0]) != 0:
  691. raise ValueError("Not a valid BIT STRING")
  692. # Fill-up self.value
  693. self.value = b''
  694. # Remove padding count byte
  695. if self.payload:
  696. self.value = self.payload[1:]
  697. class DerSetOf(DerObject):
  698. """Class to model a DER SET OF.
  699. An example of encoding is:
  700. >>> from Crypto.Util.asn1 import DerBitString
  701. >>> from binascii import hexlify, unhexlify
  702. >>> so_der = DerSetOf([4,5])
  703. >>> so_der.add(6)
  704. >>> print hexlify(so_der.encode())
  705. which will show ``3109020104020105020106``, the DER encoding
  706. of a SET OF with items 4,5, and 6.
  707. For decoding:
  708. >>> s = unhexlify(b'3109020104020105020106')
  709. >>> try:
  710. >>> so_der = DerSetOf()
  711. >>> so_der.decode(s)
  712. >>> print [x for x in so_der]
  713. >>> except ValueError:
  714. >>> print "Not a valid DER SET OF"
  715. the output will be ``[4, 5, 6]``.
  716. """
  717. def __init__(self, startSet=None, implicit=None):
  718. """Initialize the DER object as a SET OF.
  719. :Parameters:
  720. startSet : container
  721. The initial set of integers or DER encoded objects.
  722. implicit : integer
  723. The IMPLICIT tag to use for the encoded object.
  724. It overrides the universal tag for SET OF (17).
  725. """
  726. DerObject.__init__(self, 0x11, b'', implicit, True)
  727. self._seq = []
  728. # All elements must be of the same type (and therefore have the
  729. # same leading octet)
  730. self._elemOctet = None
  731. if startSet:
  732. for e in startSet:
  733. self.add(e)
  734. def __getitem__(self, n):
  735. return self._seq[n]
  736. def __iter__(self):
  737. return iter(self._seq)
  738. def __len__(self):
  739. return len(self._seq)
  740. def add(self, elem):
  741. """Add an element to the set.
  742. Args:
  743. elem (byte string or integer):
  744. An element of the same type of objects already in the set.
  745. It can be an integer or a DER encoded object.
  746. """
  747. if _is_number(elem):
  748. eo = 0x02
  749. elif isinstance(elem, DerObject):
  750. eo = self._tag_octet
  751. else:
  752. eo = bord(elem[0])
  753. if self._elemOctet != eo:
  754. if self._elemOctet is not None:
  755. raise ValueError("New element does not belong to the set")
  756. self._elemOctet = eo
  757. if elem not in self._seq:
  758. self._seq.append(elem)
  759. def decode(self, der_encoded, strict=False):
  760. """Decode a complete SET OF DER element, and re-initializes this
  761. object with it.
  762. DER INTEGERs are decoded into Python integers. Any other DER
  763. element is left undecoded; its validity is not checked.
  764. Args:
  765. der_encoded (byte string): a complete DER BIT SET OF.
  766. strict (boolean):
  767. Whether decoding must check for strict DER compliancy.
  768. Raises:
  769. ValueError: in case of parsing errors.
  770. """
  771. return DerObject.decode(self, der_encoded, strict)
  772. def _decodeFromStream(self, s, strict):
  773. """Decode a complete DER SET OF from a file."""
  774. self._seq = []
  775. # Fill up self.payload
  776. DerObject._decodeFromStream(self, s, strict)
  777. # Add one item at a time to self.seq, by scanning self.payload
  778. p = BytesIO_EOF(self.payload)
  779. setIdOctet = -1
  780. while p.remaining_data() > 0:
  781. p.set_bookmark()
  782. der = DerObject()
  783. der._decodeFromStream(p, strict)
  784. # Verify that all members are of the same type
  785. if setIdOctet < 0:
  786. setIdOctet = der._tag_octet
  787. else:
  788. if setIdOctet != der._tag_octet:
  789. raise ValueError("Not all elements are of the same DER type")
  790. # Parse INTEGERs differently
  791. if setIdOctet != 0x02:
  792. self._seq.append(p.data_since_bookmark())
  793. else:
  794. derInt = DerInteger()
  795. derInt.decode(p.data_since_bookmark(), strict)
  796. self._seq.append(derInt.value)
  797. # end
  798. def encode(self):
  799. """Return this SET OF DER element, fully encoded as a
  800. binary string.
  801. """
  802. # Elements in the set must be ordered in lexicographic order
  803. ordered = []
  804. for item in self._seq:
  805. if _is_number(item):
  806. bys = DerInteger(item).encode()
  807. elif isinstance(item, DerObject):
  808. bys = item.encode()
  809. else:
  810. bys = item
  811. ordered.append(bys)
  812. ordered.sort()
  813. self.payload = b''.join(ordered)
  814. return DerObject.encode(self)