CryptoParser 1.2.0__tar.gz → 1.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/.gitlab-ci.yml +1 -1
  2. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/CHANGELOG.rst +11 -0
  3. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/CryptoParser.egg-info/PKG-INFO +3 -3
  4. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/CryptoParser.egg-info/requires.txt +1 -1
  5. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/CryptoParser.egg-info/top_level.txt +0 -2
  6. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/PKG-INFO +3 -3
  7. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/__setup__.py +1 -1
  8. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/common/x509.py +1 -1
  9. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/dnsrec/record.py +57 -1
  10. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/docs/features.rst +3 -0
  11. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/pyproject.toml +3 -4
  12. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/dnsrec/test_record.py +56 -1
  13. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/.coveragerc +0 -0
  14. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/.flake8 +0 -0
  15. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/.gitignore +0 -0
  16. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/.gitmodules +0 -0
  17. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/.pylintrc +0 -0
  18. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/.readthedocs.yaml +0 -0
  19. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/CONTRIBUTING.rst +0 -0
  20. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/CryptoParser.egg-info/SOURCES.txt +0 -0
  21. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/CryptoParser.egg-info/dependency_links.txt +0 -0
  22. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/LICENSE.txt +0 -0
  23. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/MANIFEST.in +0 -0
  24. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/README.rst +0 -0
  25. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/__init__.py +0 -0
  26. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/common/__init__.py +0 -0
  27. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/common/base.py +0 -0
  28. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/common/classes.py +0 -0
  29. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/common/exception.py +0 -0
  30. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/common/field.py +0 -0
  31. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/common/parse.py +0 -0
  32. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/common/utils.py +0 -0
  33. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/dnsrec/__init__.py +0 -0
  34. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/dnsrec/txt.py +0 -0
  35. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/httpx/__init__.py +0 -0
  36. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/httpx/header.py +0 -0
  37. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/httpx/parse.py +0 -0
  38. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/httpx/version.py +0 -0
  39. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/ike/__init__.py +0 -0
  40. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/ike/common.py +0 -0
  41. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/ike/ikev1.py +0 -0
  42. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/ike/ikev2.py +0 -0
  43. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/ike/isakmp.py +0 -0
  44. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/ike/version.py +0 -0
  45. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/ssh/__init__.py +0 -0
  46. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/ssh/key.py +0 -0
  47. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/ssh/record.py +0 -0
  48. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/ssh/subprotocol.py +0 -0
  49. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/ssh/version.py +0 -0
  50. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/__init__.py +0 -0
  51. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/algorithm.py +0 -0
  52. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/ciphersuite.py +0 -0
  53. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/extension.py +0 -0
  54. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/grease.py +0 -0
  55. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/ldap.py +0 -0
  56. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/mysql.py +0 -0
  57. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/openvpn.py +0 -0
  58. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/postgresql.py +0 -0
  59. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/rdp.py +0 -0
  60. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/record.py +0 -0
  61. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/subprotocol.py +0 -0
  62. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/cryptoparser/tls/version.py +0 -0
  63. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/docs/.gitignore +0 -0
  64. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/docs/changelog.rst +0 -0
  65. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/docs/conf.py +0 -0
  66. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/docs/development.rst +0 -0
  67. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/docs/index.rst +0 -0
  68. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/setup.cfg +0 -0
  69. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/setup.py +0 -0
  70. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/__init__.py +0 -0
  71. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/__init__.py +0 -0
  72. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/certs/ecc256.badssl.com.pem +0 -0
  73. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/certs/rsa8192.badssl.com.pem +0 -0
  74. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/certs/rsa8192.badssl.com_certificate.crt +0 -0
  75. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/certs/rsa8192.badssl.com_root_ca.crt +0 -0
  76. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/certs/snakeoil_cert.pem +0 -0
  77. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/classes.py +0 -0
  78. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/test_algorithm.py +0 -0
  79. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/test_base.py +0 -0
  80. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/test_classes.py +0 -0
  81. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/test_exception.py +0 -0
  82. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/test_field.py +0 -0
  83. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/test_parse.py +0 -0
  84. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/test_utils.py +0 -0
  85. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/common/test_x509.py +0 -0
  86. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/dnsrec/__init__.py +0 -0
  87. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/dnsrec/test_txt.py +0 -0
  88. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/httpx/__init__.py +0 -0
  89. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/httpx/classes.py +0 -0
  90. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/httpx/test_header.py +0 -0
  91. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/httpx/test_version.py +0 -0
  92. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ike/__init__.py +0 -0
  93. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ike/classes.py +0 -0
  94. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ike/test_ikev1_payload.py +0 -0
  95. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ike/test_ikev1_sa.py +0 -0
  96. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ike/test_ikev2_notify.py +0 -0
  97. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ike/test_ikev2_payload.py +0 -0
  98. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ike/test_ikev2_sa.py +0 -0
  99. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ike/test_isakmp.py +0 -0
  100. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ike/test_version.py +0 -0
  101. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ssh/__init__.py +0 -0
  102. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ssh/test_ciphersuites.py +0 -0
  103. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ssh/test_key.py +0 -0
  104. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ssh/test_record.py +0 -0
  105. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ssh/test_subprotocol.py +0 -0
  106. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/ssh/test_version.py +0 -0
  107. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/__init__.py +0 -0
  108. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/classes.py +0 -0
  109. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_alert.py +0 -0
  110. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_application_data.py +0 -0
  111. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_change_cipher_spec.py +0 -0
  112. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_ciphersuite.py +0 -0
  113. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_extension.py +0 -0
  114. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_grease.py +0 -0
  115. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_handshake.py +0 -0
  116. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_ldap.py +0 -0
  117. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_mysql.py +0 -0
  118. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_openvpn.py +0 -0
  119. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_postgresql.py +0 -0
  120. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_rdp.py +0 -0
  121. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_record.py +0 -0
  122. {cryptoparser-1.2.0 → cryptoparser-1.2.1}/test/tls/test_version.py +0 -0
@@ -86,7 +86,7 @@ coveralls:
86
86
 
87
87
  obs:
88
88
  image:
89
- name: coroner/python_obs:1.0.0
89
+ name: coroner/python_obs:1.1.2
90
90
  pull_policy: always
91
91
  stage: deploy
92
92
  variables:
@@ -2,6 +2,17 @@
2
2
  Changelog
3
3
  =========
4
4
 
5
+ ------------------
6
+ 1.2.1 - 2026-06-02
7
+ ------------------
8
+
9
+ Features
10
+ ========
11
+
12
+ - DNS (``dnsrec``)
13
+
14
+ - add SSHFP DNS resource record parsing (#98)
15
+
5
16
  ------------------
6
17
  1.2.0 - 2026-05-05
7
18
  ------------------
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: CryptoParser
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: An analysis oriented security protocol parser and generator
5
5
  Author-email: Szilárd Pfeiffer <coroner@pfeifferszilard.hu>
6
6
  Maintainer-email: Szilárd Pfeiffer <coroner@pfeifferszilard.hu>
7
- License-Expression: MPL-2.0
7
+ License: MPL-2.0
8
8
  Project-URL: Homepage, https://gitlab.com/coroner/cryptoparser
9
9
  Project-URL: Changelog, https://cryptoparser.readthedocs.io/en/latest/changelog
10
10
  Project-URL: Documentation, https://cryptoparser.readthedocs.io/en/latest/
@@ -40,7 +40,7 @@ Description-Content-Type: text/x-rst
40
40
  License-File: LICENSE.txt
41
41
  Requires-Dist: asn1crypto
42
42
  Requires-Dist: attrs
43
- Requires-Dist: cryptodatahub==1.2.0
43
+ Requires-Dist: cryptodatahub==1.2.1
44
44
  Requires-Dist: urllib3
45
45
  Provides-Extra: tests
46
46
  Requires-Dist: pyfakefs; extra == "tests"
@@ -1,6 +1,6 @@
1
1
  asn1crypto
2
2
  attrs
3
- cryptodatahub==1.2.0
3
+ cryptodatahub==1.2.1
4
4
  urllib3
5
5
 
6
6
  [docs]
@@ -1,7 +1,5 @@
1
- build
2
1
  cryptoparser
3
2
  dist
4
3
  docs
5
- htmlcov
6
4
  submodules
7
5
  test
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: CryptoParser
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: An analysis oriented security protocol parser and generator
5
5
  Author-email: Szilárd Pfeiffer <coroner@pfeifferszilard.hu>
6
6
  Maintainer-email: Szilárd Pfeiffer <coroner@pfeifferszilard.hu>
7
- License-Expression: MPL-2.0
7
+ License: MPL-2.0
8
8
  Project-URL: Homepage, https://gitlab.com/coroner/cryptoparser
9
9
  Project-URL: Changelog, https://cryptoparser.readthedocs.io/en/latest/changelog
10
10
  Project-URL: Documentation, https://cryptoparser.readthedocs.io/en/latest/
@@ -40,7 +40,7 @@ Description-Content-Type: text/x-rst
40
40
  License-File: LICENSE.txt
41
41
  Requires-Dist: asn1crypto
42
42
  Requires-Dist: attrs
43
- Requires-Dist: cryptodatahub==1.2.0
43
+ Requires-Dist: cryptodatahub==1.2.1
44
44
  Requires-Dist: urllib3
45
45
  Provides-Extra: tests
46
46
  Requires-Dist: pyfakefs; extra == "tests"
@@ -12,4 +12,4 @@ __description__ = metadata['Summary']
12
12
  __author__ = metadata['Author']
13
13
  __author_email__ = metadata['Author-email']
14
14
  __url__ = 'https://gitlab.com/coroner/' + __technical_name__
15
- __license__ = metadata['License']
15
+ __license__ = metadata.get('License-Expression') or metadata['License']
@@ -55,7 +55,7 @@ class SignedCertificateTimestamp(ParsableBase, Serializable):
55
55
  )
56
56
  timestamp = attr.ib(validator=attr.validators.instance_of(datetime.datetime))
57
57
  extensions = attr.ib(
58
- validator=attr.validators.deep_iterable(member_validator=attr.validators.instance_of(CtExtensions))
58
+ validator=attr.validators.instance_of(CtExtensions)
59
59
  )
60
60
  signature_algorithm = attr.ib(validator=attr.validators.in_(TlsSignatureAndHashAlgorithm))
61
61
  signature = attr.ib(
@@ -18,7 +18,13 @@ from cryptodatahub.common.key import (
18
18
  PublicKeyParamsRsa,
19
19
  )
20
20
 
21
- from cryptodatahub.dnsrec.algorithm import DnsRrType, DnsSecAlgorithm, DnsSecDigestType
21
+ from cryptodatahub.dnsrec.algorithm import (
22
+ DnsRrType,
23
+ DnsSecAlgorithm,
24
+ DnsSecDigestType,
25
+ SshFpAlgorithm,
26
+ SshFpFingerprintType,
27
+ )
22
28
 
23
29
  from cryptoparser.common.base import NumericRangeParsableBase, OneByteEnumParsable, Serializable, TwoByteEnumParsable
24
30
  from cryptoparser.common.exception import NotEnoughData
@@ -478,6 +484,56 @@ class DnsRecordMx(ParsableBase):
478
484
  return composer.composed_bytes
479
485
 
480
486
 
487
+ class SshFpAlgorithmFactory(OneByteEnumParsable):
488
+ @classmethod
489
+ def get_enum_class(cls):
490
+ return SshFpAlgorithm
491
+
492
+ @abc.abstractmethod
493
+ def compose(self):
494
+ raise NotImplementedError()
495
+
496
+
497
+ class SshFpFingerprintTypeFactory(OneByteEnumParsable):
498
+ @classmethod
499
+ def get_enum_class(cls):
500
+ return SshFpFingerprintType
501
+
502
+ @abc.abstractmethod
503
+ def compose(self):
504
+ raise NotImplementedError()
505
+
506
+
507
+ @attr.s
508
+ class DnsRecordSshfp(ParsableBase, Serializable):
509
+ HEADER_SIZE = 2
510
+
511
+ algorithm = attr.ib(validator=attr.validators.instance_of(SshFpAlgorithm))
512
+ fingerprint_type = attr.ib(validator=attr.validators.instance_of(SshFpFingerprintType))
513
+ fingerprint = attr.ib(validator=attr.validators.instance_of((bytes, bytearray)))
514
+
515
+ @classmethod
516
+ def _parse(cls, parsable):
517
+ if len(parsable) < cls.HEADER_SIZE:
518
+ raise NotEnoughData(cls.HEADER_SIZE - len(parsable))
519
+
520
+ parser = ParserBinary(parsable)
521
+ parser.parse_parsable('algorithm', SshFpAlgorithmFactory)
522
+ parser.parse_parsable('fingerprint_type', SshFpFingerprintTypeFactory)
523
+ parser.parse_raw('fingerprint', parser.unparsed_length)
524
+
525
+ return cls(**parser), parser.parsed_length
526
+
527
+ def compose(self):
528
+ composer = ComposerBinary()
529
+
530
+ composer.compose_numeric_enum_coded(self.algorithm)
531
+ composer.compose_numeric_enum_coded(self.fingerprint_type)
532
+ composer.compose_raw(self.fingerprint)
533
+
534
+ return composer.composed_bytes
535
+
536
+
481
537
  @attr.s
482
538
  class DnsRecordTxt(ParsableBase):
483
539
  HEADER_SIZE = 1
@@ -105,6 +105,7 @@ Only features that cannot be or difficultly implemented by some of the most popu
105
105
  1. supports each cipher suites discussed on `ciphersuite.info <https://ciphersuite.info>`__
106
106
  2. supports `GOST <https://en.wikipedia.org/wiki/GOST>`__ (national standards of the Russian Federation and CIS
107
107
  countries) cipher suites
108
+ 3. supports `ShangMi (SM) <https://www.rfc-editor.org/rfc/rfc8998>`__ (national standards of China) cipher suites
108
109
 
109
110
  - application layer
110
111
 
@@ -142,3 +143,5 @@ Domain Name System (DNS)
142
143
  - `DNSKEY <https://www.rfc-editor.org/rfc/rfc4034#section-2>`__
143
144
  - `DS <https://www.rfc-editor.org/rfc/rfc4034#section-5>`__
144
145
  - `RRSIG <https://www.rfc-editor.org/rfc/rfc4034#section-3>`__
146
+
147
+ - `SSHFP <https://www.rfc-editor.org/rfc/rfc4255>`__ (SSH host key fingerprints)
@@ -4,7 +4,7 @@ build-backend = 'setuptools.build_meta'
4
4
 
5
5
  [project]
6
6
  name = 'CryptoParser'
7
- version = '1.2.0'
7
+ version = '1.2.1'
8
8
  description = 'An analysis oriented security protocol parser and generator'
9
9
  authors = [
10
10
  {name = 'Szilárd Pfeiffer', email = 'coroner@pfeifferszilard.hu'}
@@ -42,13 +42,12 @@ classifiers=[
42
42
 
43
43
  keywords=['ssl', 'tls', 'gost', 'ja3', 'ldap', 'rdp', 'ssh', 'hsts', 'dns', 'ike']
44
44
  readme = {file = 'README.rst', content-type = 'text/x-rst'}
45
- license = 'MPL-2.0'
46
- license-files = ['LICENSE.txt']
45
+ license = {text = 'MPL-2.0'}
47
46
 
48
47
  dependencies = [
49
48
  'asn1crypto',
50
49
  'attrs',
51
- 'cryptodatahub==1.2.0',
50
+ 'cryptodatahub==1.2.1',
52
51
  'urllib3',
53
52
  ]
54
53
 
@@ -16,7 +16,13 @@ from cryptodatahub.common.key import (
16
16
  PublicKeyParamsRsa,
17
17
  )
18
18
 
19
- from cryptodatahub.dnsrec.algorithm import DnsSecAlgorithm, DnsSecDigestType, DnsRrType
19
+ from cryptodatahub.dnsrec.algorithm import (
20
+ DnsSecAlgorithm,
21
+ DnsSecDigestType,
22
+ DnsRrType,
23
+ SshFpAlgorithm,
24
+ SshFpFingerprintType,
25
+ )
20
26
 
21
27
  from cryptoparser.common.exception import NotEnoughData
22
28
  from cryptoparser.dnsrec.record import (
@@ -25,6 +31,7 @@ from cryptoparser.dnsrec.record import (
25
31
  DnsRecordDs,
26
32
  DnsRecordMx,
27
33
  DnsRecordRrsig,
34
+ DnsRecordSshfp,
28
35
  DnsRecordTxt,
29
36
  DnsRrTypePrivate,
30
37
  DnsSecFlag,
@@ -549,3 +556,51 @@ class TestDnsRecordTxt(unittest.TestCase):
549
556
 
550
557
  def test_compose(self):
551
558
  self.assertEqual(self.record_single.compose(), self.record_bytes_single)
559
+
560
+
561
+ class TestDnsRecordSshfp(unittest.TestCase):
562
+ def setUp(self):
563
+ self.record_rsa_sha1_bytes = bytes(
564
+ b'\x01' + # algorithm: RSA
565
+ b'\x01' + # fingerprint type: SHA-1
566
+ b'\xde\xad\xbe\xef' * 5 # fingerprint: 20 bytes
567
+ )
568
+ self.record_rsa_sha1 = DnsRecordSshfp(
569
+ algorithm=SshFpAlgorithm.RSA,
570
+ fingerprint_type=SshFpFingerprintType.SHA1,
571
+ fingerprint=b'\xde\xad\xbe\xef' * 5,
572
+ )
573
+
574
+ self.record_ecdsa_sha256_bytes = bytes(
575
+ b'\x03' + # algorithm: ECDSA
576
+ b'\x02' + # fingerprint type: SHA-256
577
+ b'\xab\xcd\xef\x01' * 8 # fingerprint: 32 bytes
578
+ )
579
+ self.record_ecdsa_sha256 = DnsRecordSshfp(
580
+ algorithm=SshFpAlgorithm.ECDSA,
581
+ fingerprint_type=SshFpFingerprintType.SHA2_256,
582
+ fingerprint=b'\xab\xcd\xef\x01' * 8,
583
+ )
584
+
585
+ def test_error_not_enough_data(self):
586
+ with self.assertRaises(NotEnoughData) as context_manager:
587
+ DnsRecordSshfp.parse_exact_size(b'\x01')
588
+
589
+ self.assertEqual(
590
+ context_manager.exception.bytes_needed,
591
+ DnsRecordSshfp.HEADER_SIZE - 1
592
+ )
593
+
594
+ def test_parse(self):
595
+ self.assertEqual(
596
+ DnsRecordSshfp.parse_exact_size(self.record_rsa_sha1_bytes),
597
+ self.record_rsa_sha1
598
+ )
599
+ self.assertEqual(
600
+ DnsRecordSshfp.parse_exact_size(self.record_ecdsa_sha256_bytes),
601
+ self.record_ecdsa_sha256
602
+ )
603
+
604
+ def test_compose(self):
605
+ self.assertEqual(self.record_rsa_sha1.compose(), self.record_rsa_sha1_bytes)
606
+ self.assertEqual(self.record_ecdsa_sha256.compose(), self.record_ecdsa_sha256_bytes)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes