http-message-signatures 0.5.0__tar.gz → 0.6.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.
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/.github/workflows/ci.yml +9 -6
- http_message_signatures-0.6.1/.github/workflows/release.yml +21 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/Changes.rst +11 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/LICENSE +0 -24
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/Makefile +1 -1
- http_message_signatures-0.6.1/NOTICE +10 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/PKG-INFO +24 -17
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/README.rst +6 -3
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/common.mk +1 -7
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/http_message_signatures/_algorithms.py +2 -2
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/http_message_signatures/signatures.py +5 -2
- http_message_signatures-0.6.1/pyproject.toml +54 -0
- http_message_signatures-0.6.1/setup.cfg +3 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/test/test.py +39 -4
- http-message-signatures-0.5.0/http_message_signatures/version.py +0 -16
- http-message-signatures-0.5.0/http_message_signatures.egg-info/PKG-INFO +0 -127
- http-message-signatures-0.5.0/http_message_signatures.egg-info/SOURCES.txt +0 -36
- http-message-signatures-0.5.0/http_message_signatures.egg-info/dependency_links.txt +0 -1
- http-message-signatures-0.5.0/http_message_signatures.egg-info/requires.txt +0 -11
- http-message-signatures-0.5.0/http_message_signatures.egg-info/top_level.txt +0 -1
- http-message-signatures-0.5.0/pyproject.toml +0 -7
- http-message-signatures-0.5.0/setup.cfg +0 -8
- http-message-signatures-0.5.0/setup.py +0 -49
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/.github/FUNDING.yml +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/.gitignore +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/docs/conf.py +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/docs/index.rst +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/http_message_signatures/__init__.py +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/http_message_signatures/algorithms.py +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/http_message_signatures/exceptions.py +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/http_message_signatures/py.typed +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/http_message_signatures/resolvers.py +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/http_message_signatures/structures.py +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/test/test-key-ecc-p256.key +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/test/test-key-ecc-p256.pem +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/test/test-key-ed25519.key +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/test/test-key-ed25519.pem +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/test/test-key-rsa-pss.key +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/test/test-key-rsa-pss.pem +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/test/test-key-rsa.key +0 -0
- {http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/test/test-key-rsa.pem +0 -0
@@ -10,7 +10,7 @@ jobs:
|
|
10
10
|
fail-fast: false
|
11
11
|
max-parallel: 8
|
12
12
|
matrix:
|
13
|
-
python-version: ["3.
|
13
|
+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
14
14
|
|
15
15
|
steps:
|
16
16
|
- uses: actions/checkout@v4
|
@@ -23,13 +23,16 @@ jobs:
|
|
23
23
|
run: pip install .[tests]
|
24
24
|
- name: Test
|
25
25
|
run: make test
|
26
|
-
black:
|
27
|
-
runs-on: ubuntu-22.04
|
28
|
-
steps:
|
29
|
-
- uses: actions/checkout@v4
|
30
|
-
- uses: psf/black@stable
|
31
26
|
isort:
|
32
27
|
runs-on: ubuntu-22.04
|
33
28
|
steps:
|
34
29
|
- uses: actions/checkout@v4
|
35
30
|
- uses: isort/isort-action@v1.1.0
|
31
|
+
ruff:
|
32
|
+
runs-on: ubuntu-latest
|
33
|
+
steps:
|
34
|
+
- uses: actions/checkout@v4
|
35
|
+
- uses: astral-sh/ruff-action@v3
|
36
|
+
- uses: astral-sh/ruff-action@v3
|
37
|
+
with:
|
38
|
+
args: "format --check"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
name: Publish release to PyPI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
tags:
|
6
|
+
- 'v[0-9]+.[0-9]+.[0-9]+'
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
pypi-publish:
|
10
|
+
name: Build and upload release to PyPI
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
environment: release
|
13
|
+
permissions:
|
14
|
+
id-token: write
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v4
|
17
|
+
- uses: actions/setup-python@v5
|
18
|
+
- run: pip install build
|
19
|
+
- run: python -m build
|
20
|
+
- name: Publish package distributions to PyPI
|
21
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
@@ -1,3 +1,14 @@
|
|
1
|
+
Changes for v0.6.1 (2025-05-29)
|
2
|
+
===============================
|
3
|
+
|
4
|
+
- Switch to trusted publishing
|
5
|
+
|
6
|
+
Changes for v0.6.0 (2025-05-29)
|
7
|
+
===============================
|
8
|
+
|
9
|
+
- [http-message-signatures-add] Add support for ‘tag’ signature
|
10
|
+
parameter (#17)
|
11
|
+
|
1
12
|
Changes for v0.5.0 (2024-02-21)
|
2
13
|
===============================
|
3
14
|
|
@@ -165,27 +165,3 @@ incurred by, or claims asserted against, such Contributor by reason of your
|
|
165
165
|
accepting any such warranty or additional liability.
|
166
166
|
|
167
167
|
END OF TERMS AND CONDITIONS
|
168
|
-
|
169
|
-
APPENDIX: How to apply the Apache License to your work
|
170
|
-
|
171
|
-
To apply the Apache License to your work, attach the following boilerplate
|
172
|
-
notice, with the fields enclosed by brackets "[]" replaced with your own
|
173
|
-
identifying information. (Don't include the brackets!) The text should be
|
174
|
-
enclosed in the appropriate comment syntax for the file format. We also
|
175
|
-
recommend that a file or class name and description of purpose be included on
|
176
|
-
the same "printed page" as the copyright notice for easier identification within
|
177
|
-
third-party archives.
|
178
|
-
|
179
|
-
Copyright [yyyy] [name of copyright owner]
|
180
|
-
|
181
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
182
|
-
you may not use this file except in compliance with the License.
|
183
|
-
You may obtain a copy of the License at
|
184
|
-
|
185
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
186
|
-
|
187
|
-
Unless required by applicable law or agreed to in writing, software
|
188
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
189
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
190
|
-
See the License for the specific language governing permissions and
|
191
|
-
limitations under the License.
|
@@ -0,0 +1,10 @@
|
|
1
|
+
http-message-signatures is a free open source implementation of the
|
2
|
+
IETF HTTP Message Signatures standard, RFC 9421. This project is
|
3
|
+
staffed by volunteers. If you are using http-message-signatures in a
|
4
|
+
for-profit project, please contribute to its development and
|
5
|
+
maintenance using the "Sponsor" button on the GitHub project page,
|
6
|
+
https://github.com/pyauth/http-message-signatures. If you are looking
|
7
|
+
for support with commercial applications based on
|
8
|
+
http-message-signatures, please donate and contact its developers
|
9
|
+
using the issue tracker on the http-message-signatures project page or
|
10
|
+
the contact information listed in README.rst.
|
@@ -1,13 +1,15 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: http-message-signatures
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.6.1
|
4
4
|
Summary: An implementation of the IETF HTTP Message Signatures draft standard
|
5
|
-
|
5
|
+
Project-URL: Homepage, https://github.com/pyauth/http-message-signatures
|
6
6
|
Author: Andrey Kislyuk
|
7
7
|
Author-email: kislyuk@gmail.com
|
8
|
+
Maintainer: Andrey Kislyuk
|
9
|
+
Maintainer-email: kislyuk@gmail.com
|
8
10
|
License: Apache Software License
|
9
|
-
|
10
|
-
|
11
|
+
License-File: LICENSE
|
12
|
+
License-File: NOTICE
|
11
13
|
Classifier: Intended Audience :: Developers
|
12
14
|
Classifier: License :: OSI Approved :: Apache Software License
|
13
15
|
Classifier: Operating System :: MacOS :: MacOS X
|
@@ -18,24 +20,26 @@ Classifier: Programming Language :: Python :: 3.9
|
|
18
20
|
Classifier: Programming Language :: Python :: 3.10
|
19
21
|
Classifier: Programming Language :: Python :: 3.11
|
20
22
|
Classifier: Programming Language :: Python :: 3.12
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
21
24
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
22
|
-
|
23
|
-
Requires-Dist: http-sfv>=0.9.3
|
25
|
+
Requires-Python: >=3.8
|
24
26
|
Requires-Dist: cryptography>=36.0.2
|
27
|
+
Requires-Dist: http-sfv>=0.9.3
|
25
28
|
Provides-Extra: tests
|
26
|
-
Requires-Dist:
|
27
|
-
Requires-Dist: coverage; extra ==
|
28
|
-
Requires-Dist:
|
29
|
-
Requires-Dist:
|
30
|
-
Requires-Dist:
|
31
|
-
Requires-Dist:
|
32
|
-
Requires-Dist:
|
29
|
+
Requires-Dist: build; extra == 'tests'
|
30
|
+
Requires-Dist: coverage; extra == 'tests'
|
31
|
+
Requires-Dist: flake8; extra == 'tests'
|
32
|
+
Requires-Dist: mypy; extra == 'tests'
|
33
|
+
Requires-Dist: requests; extra == 'tests'
|
34
|
+
Requires-Dist: ruff; extra == 'tests'
|
35
|
+
Requires-Dist: wheel; extra == 'tests'
|
36
|
+
Description-Content-Type: text/x-rst
|
33
37
|
|
34
38
|
http-message-signatures: An implementation of RFC 9421, the IETF HTTP Message Signatures standard
|
35
39
|
=================================================================================================
|
36
40
|
|
37
41
|
*http-message-signatures* is an implementation of the IETF
|
38
|
-
`RFC 9421 HTTP Message Signatures <https://datatracker.ietf.org/doc/rfc9421/>`_
|
42
|
+
`RFC 9421 HTTP Message Signatures <https://datatracker.ietf.org/doc/rfc9421/>`_ standard in
|
39
43
|
Python.
|
40
44
|
|
41
45
|
Installation
|
@@ -107,7 +111,7 @@ digest etc.)
|
|
107
111
|
|
108
112
|
Authors
|
109
113
|
-------
|
110
|
-
* Andrey Kislyuk
|
114
|
+
* `Andrey Kislyuk <https://kislyuk.com>`
|
111
115
|
|
112
116
|
Links
|
113
117
|
-----
|
@@ -124,4 +128,7 @@ Please report bugs, issues, feature requests, etc. on `GitHub <https://github.co
|
|
124
128
|
|
125
129
|
License
|
126
130
|
-------
|
127
|
-
Licensed under the terms of the
|
131
|
+
Copyright 2017-2024, Andrey Kislyuk and http-message-signatures contributors. Licensed under the terms of the
|
132
|
+
`Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>`_. Distribution of attribution information,
|
133
|
+
LICENSE and NOTICE files with source copies of this package and derivative works is **REQUIRED** as specified by the
|
134
|
+
Apache License.
|
@@ -2,7 +2,7 @@ http-message-signatures: An implementation of RFC 9421, the IETF HTTP Message Si
|
|
2
2
|
=================================================================================================
|
3
3
|
|
4
4
|
*http-message-signatures* is an implementation of the IETF
|
5
|
-
`RFC 9421 HTTP Message Signatures <https://datatracker.ietf.org/doc/rfc9421/>`_
|
5
|
+
`RFC 9421 HTTP Message Signatures <https://datatracker.ietf.org/doc/rfc9421/>`_ standard in
|
6
6
|
Python.
|
7
7
|
|
8
8
|
Installation
|
@@ -74,7 +74,7 @@ digest etc.)
|
|
74
74
|
|
75
75
|
Authors
|
76
76
|
-------
|
77
|
-
* Andrey Kislyuk
|
77
|
+
* `Andrey Kislyuk <https://kislyuk.com>`
|
78
78
|
|
79
79
|
Links
|
80
80
|
-----
|
@@ -91,4 +91,7 @@ Please report bugs, issues, feature requests, etc. on `GitHub <https://github.co
|
|
91
91
|
|
92
92
|
License
|
93
93
|
-------
|
94
|
-
Licensed under the terms of the
|
94
|
+
Copyright 2017-2024, Andrey Kislyuk and http-message-signatures contributors. Licensed under the terms of the
|
95
|
+
`Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>`_. Distribution of attribution information,
|
96
|
+
LICENSE and NOTICE files with source copies of this package and derivative works is **REQUIRED** as specified by the
|
97
|
+
Apache License.
|
@@ -18,9 +18,8 @@ release:
|
|
18
18
|
@if ! type -P pandoc; then echo "Please install pandoc"; exit 1; fi
|
19
19
|
@if ! type -P sponge; then echo "Please install moreutils"; exit 1; fi
|
20
20
|
@if ! type -P gh; then echo "Please install gh"; exit 1; fi
|
21
|
-
@if ! type -P twine; then echo "Please install twine"; exit 1; fi
|
22
21
|
git pull
|
23
|
-
git clean -x --force $$(
|
22
|
+
git clean -x --force $$(ls */__init__.py | xargs dirname)
|
24
23
|
TAG_MSG=$$(mktemp); \
|
25
24
|
echo "# Changes for ${TAG} ($$(date +%Y-%m-%d))" > $$TAG_MSG; \
|
26
25
|
git log --pretty=format:%s $$(git describe --abbrev=0)..HEAD >> $$TAG_MSG; \
|
@@ -32,10 +31,5 @@ release:
|
|
32
31
|
git push --follow-tags
|
33
32
|
$(MAKE) install
|
34
33
|
gh release create ${TAG} dist/*.whl --notes="$$(git tag --list ${TAG} -n99 | perl -pe 's/^\S+\s*// if $$. == 1' | sed 's/^\s\s\s\s//')"
|
35
|
-
$(MAKE) release-pypi
|
36
|
-
|
37
|
-
release-pypi:
|
38
|
-
python -m build
|
39
|
-
twine upload dist/*.tar.gz dist/*.whl --verbose
|
40
34
|
|
41
35
|
.PHONY: release
|
@@ -91,9 +91,9 @@ class ECDSA_P256_SHA256(HTTPSignatureAlgorithm, PEMKeyLoader):
|
|
91
91
|
raise HTTPMessageSignaturesException("Unexpected public key type")
|
92
92
|
if self.private_key and not isinstance(self.private_key, ec.EllipticCurvePrivateKey):
|
93
93
|
raise HTTPMessageSignaturesException("Unexpected private key type")
|
94
|
-
if self.public_key and
|
94
|
+
if self.public_key and not isinstance(self.public_key.curve, ec.SECP256R1):
|
95
95
|
raise HTTPMessageSignaturesException("Unexpected elliptic curve type in public key")
|
96
|
-
if self.private_key and
|
96
|
+
if self.private_key and not isinstance(self.private_key.curve, ec.SECP256R1):
|
97
97
|
raise HTTPMessageSignaturesException("Unexpected elliptic curve type in private key")
|
98
98
|
self.signature_algorithm = ec.ECDSA(hashes.SHA256())
|
99
99
|
|
@@ -14,7 +14,7 @@ logger = logging.getLogger(__name__)
|
|
14
14
|
|
15
15
|
|
16
16
|
class HTTPSignatureHandler:
|
17
|
-
signature_metadata_parameters = {"alg", "created", "expires", "keyid", "nonce"}
|
17
|
+
signature_metadata_parameters = {"alg", "created", "expires", "keyid", "nonce", "tag"}
|
18
18
|
|
19
19
|
def __init__(
|
20
20
|
self,
|
@@ -46,7 +46,7 @@ class HTTPSignatureHandler:
|
|
46
46
|
raise HTTPMessageSignaturesException(f'Component ID "{component_key}" contains newline character')
|
47
47
|
if component_key in sig_elements:
|
48
48
|
raise HTTPMessageSignaturesException(
|
49
|
-
f'Component ID "{component_key}" appeared multiple times in
|
49
|
+
f'Component ID "{component_key}" appeared multiple times in signature input'
|
50
50
|
)
|
51
51
|
sig_elements[component_key] = component_value
|
52
52
|
sig_params_node = http_sfv.InnerList(covered_component_ids)
|
@@ -79,6 +79,7 @@ class HTTPMessageSigner(HTTPSignatureHandler):
|
|
79
79
|
expires: Optional[datetime.datetime] = None,
|
80
80
|
nonce: Optional[str] = None,
|
81
81
|
label: Optional[str] = None,
|
82
|
+
tag: Optional[str] = None,
|
82
83
|
include_alg: bool = True,
|
83
84
|
covered_component_ids: Sequence[str] = ("@method", "@authority", "@target-uri"),
|
84
85
|
):
|
@@ -93,6 +94,8 @@ class HTTPMessageSigner(HTTPSignatureHandler):
|
|
93
94
|
signature_params["expires"] = int(expires.timestamp())
|
94
95
|
if nonce:
|
95
96
|
signature_params["nonce"] = nonce
|
97
|
+
if tag:
|
98
|
+
signature_params["tag"] = tag
|
96
99
|
if include_alg:
|
97
100
|
signature_params["alg"] = self.signature_algorithm.algorithm_id
|
98
101
|
covered_component_nodes = self._parse_covered_component_ids(covered_component_ids)
|
@@ -0,0 +1,54 @@
|
|
1
|
+
[project]
|
2
|
+
name = "http-message-signatures"
|
3
|
+
description = "An implementation of the IETF HTTP Message Signatures draft standard"
|
4
|
+
readme = "README.rst"
|
5
|
+
requires-python = ">=3.8"
|
6
|
+
license = {text = "Apache Software License"}
|
7
|
+
authors = [{ name = "Andrey Kislyuk"}, {email = "kislyuk@gmail.com" }]
|
8
|
+
maintainers = [{ name = "Andrey Kislyuk"}, {email = "kislyuk@gmail.com" }]
|
9
|
+
dynamic = ["version"]
|
10
|
+
classifiers = [
|
11
|
+
"Intended Audience :: Developers",
|
12
|
+
"License :: OSI Approved :: Apache Software License",
|
13
|
+
"Operating System :: MacOS :: MacOS X",
|
14
|
+
"Operating System :: POSIX",
|
15
|
+
"Programming Language :: Python",
|
16
|
+
"Programming Language :: Python :: 3.8",
|
17
|
+
"Programming Language :: Python :: 3.9",
|
18
|
+
"Programming Language :: Python :: 3.10",
|
19
|
+
"Programming Language :: Python :: 3.11",
|
20
|
+
"Programming Language :: Python :: 3.12",
|
21
|
+
"Programming Language :: Python :: 3.13",
|
22
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
23
|
+
]
|
24
|
+
dependencies = [
|
25
|
+
"http-sfv >= 0.9.3",
|
26
|
+
"cryptography >= 36.0.2",
|
27
|
+
]
|
28
|
+
|
29
|
+
[project.urls]
|
30
|
+
Homepage = "https://github.com/pyauth/http-message-signatures"
|
31
|
+
|
32
|
+
[project.optional-dependencies]
|
33
|
+
tests = [
|
34
|
+
"flake8",
|
35
|
+
"coverage",
|
36
|
+
"build",
|
37
|
+
"wheel",
|
38
|
+
"mypy",
|
39
|
+
"requests",
|
40
|
+
"ruff",
|
41
|
+
]
|
42
|
+
|
43
|
+
[build-system]
|
44
|
+
requires = ["hatchling", "hatch-vcs"]
|
45
|
+
build-backend = "hatchling.build"
|
46
|
+
|
47
|
+
[tool.hatch.version]
|
48
|
+
source = "vcs"
|
49
|
+
|
50
|
+
[tool.isort]
|
51
|
+
profile = "black"
|
52
|
+
|
53
|
+
[tool.ruff]
|
54
|
+
line-length = 120
|
@@ -31,7 +31,7 @@ from http_message_signatures.algorithms import ( # noqa
|
|
31
31
|
)
|
32
32
|
|
33
33
|
test_shared_secret = base64.b64decode(
|
34
|
-
"
|
34
|
+
"uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBtbmHhIDi6pcl8jsasjlTMtDQ=="
|
35
35
|
)
|
36
36
|
|
37
37
|
|
@@ -59,7 +59,7 @@ class TestHTTPMessageSignatures(unittest.TestCase):
|
|
59
59
|
self.test_request = request.prepare()
|
60
60
|
self.test_request.headers["Date"] = "Tue, 20 Apr 2021 02:07:55 GMT"
|
61
61
|
self.test_request.headers["Content-Digest"] = (
|
62
|
-
"sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+TaPm+
|
62
|
+
"sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==:"
|
63
63
|
)
|
64
64
|
self.test_response = requests.Response()
|
65
65
|
self.test_response.request = self.test_request
|
@@ -68,7 +68,7 @@ class TestHTTPMessageSignatures(unittest.TestCase):
|
|
68
68
|
"Date": "Tue, 20 Apr 2021 02:07:56 GMT",
|
69
69
|
"Content-Type": "application/json",
|
70
70
|
"Content-Digest": (
|
71
|
-
"sha-512=:JlEy2bfUz7WrWIjc1qV6KVLpdr/7L5/L4h7Sxvh6sNHpDQWDCL+
|
71
|
+
"sha-512=:JlEy2bfUz7WrWIjc1qV6KVLpdr/7L5/L4h7Sxvh6sNHpDQWDCL+GauFQWcZBvVDhiyOnAQsxzZFYwi0wDH+1pw==:"
|
72
72
|
),
|
73
73
|
"Content-Length": "23",
|
74
74
|
}
|
@@ -205,7 +205,7 @@ class TestHTTPMessageSignatures(unittest.TestCase):
|
|
205
205
|
verifier = HTTPMessageVerifier(signature_algorithm=ECDSA_P256_SHA256, key_resolver=self.key_resolver)
|
206
206
|
self.verify(verifier, self.test_response)
|
207
207
|
self.test_response.headers["Signature"] = (
|
208
|
-
"sig-b24=:0Ry6HsvzS5VmA6HlfBYS/
|
208
|
+
"sig-b24=:0Ry6HsvzS5VmA6HlfBYS/fYYeNs7fYuA7s0tAdxfUlPGv0CSVuwrrzBOjcCFHTxVRJ01wjvSzM2BetJauj8dsw==:"
|
209
209
|
)
|
210
210
|
self.verify(verifier, self.test_response)
|
211
211
|
|
@@ -262,6 +262,41 @@ class TestHTTPMessageSignatures(unittest.TestCase):
|
|
262
262
|
with self.assertRaises(InvalidSignature):
|
263
263
|
verifier.verify(self.test_request, max_age=self.max_age)
|
264
264
|
|
265
|
+
def test_http_message_signatures_B27(self):
|
266
|
+
signer = HTTPMessageSigner(signature_algorithm=ED25519, key_resolver=self.key_resolver)
|
267
|
+
signer.sign(
|
268
|
+
self.test_request,
|
269
|
+
key_id="test-key-ed25519",
|
270
|
+
covered_component_ids=("date", "@method", "@path", "@authority", "content-type", "content-length"),
|
271
|
+
created=datetime.fromtimestamp(1618884473),
|
272
|
+
label="sig-b27",
|
273
|
+
tag="tag-b27",
|
274
|
+
include_alg=False,
|
275
|
+
)
|
276
|
+
self.assertEqual(
|
277
|
+
self.test_request.headers["Signature-Input"],
|
278
|
+
(
|
279
|
+
'sig-b27=("date" "@method" "@path" "@authority" "content-type" "content-length");'
|
280
|
+
'created=1618884473;keyid="test-key-ed25519";tag="tag-b27"'
|
281
|
+
),
|
282
|
+
)
|
283
|
+
signature = "sig-b27=:pDPhW4vxi28JZfogrM4NLeYhZKW+TYDko8KtzCFoTOFeGCCSivD0iVcIuT9gqM6AtGfgzqQU/GaoLqh8sC6bCg==:"
|
284
|
+
self.assertEqual(self.test_request.headers["Signature"], signature)
|
285
|
+
verifier = HTTPMessageVerifier(signature_algorithm=ED25519, key_resolver=self.key_resolver)
|
286
|
+
result = self.verify(verifier, self.test_request)[0]
|
287
|
+
|
288
|
+
self.assertEqual(result.parameters["keyid"], "test-key-ed25519")
|
289
|
+
self.assertEqual(result.parameters["tag"], "tag-b27")
|
290
|
+
self.assertIn("created", result.parameters)
|
291
|
+
self.assertEqual(result.label, "sig-b27")
|
292
|
+
|
293
|
+
self.test_request.headers["Signature"] = "sig-b26=:pxcQw6G3AjtMBQjwo8XzkZf/bws5LelbaMk5rGIGtE8=:"
|
294
|
+
with self.assertRaises(InvalidSignature):
|
295
|
+
verifier.verify(self.test_request, max_age=self.max_age)
|
296
|
+
self.test_request.headers["Signature"] = signature[::-1]
|
297
|
+
with self.assertRaises(InvalidSignature):
|
298
|
+
verifier.verify(self.test_request, max_age=self.max_age)
|
299
|
+
|
265
300
|
def test_query_parameters(self):
|
266
301
|
signer = HTTPMessageSigner(signature_algorithm=HMAC_SHA256, key_resolver=self.key_resolver)
|
267
302
|
signer.sign(
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# file generated by setuptools_scm
|
2
|
-
# don't change, don't track in version control
|
3
|
-
TYPE_CHECKING = False
|
4
|
-
if TYPE_CHECKING:
|
5
|
-
from typing import Tuple, Union
|
6
|
-
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
7
|
-
else:
|
8
|
-
VERSION_TUPLE = object
|
9
|
-
|
10
|
-
version: str
|
11
|
-
__version__: str
|
12
|
-
__version_tuple__: VERSION_TUPLE
|
13
|
-
version_tuple: VERSION_TUPLE
|
14
|
-
|
15
|
-
__version__ = version = '0.5.0'
|
16
|
-
__version_tuple__ = version_tuple = (0, 5, 0)
|
@@ -1,127 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: http-message-signatures
|
3
|
-
Version: 0.5.0
|
4
|
-
Summary: An implementation of the IETF HTTP Message Signatures draft standard
|
5
|
-
Home-page: https://github.com/pyauth/http-message-signatures
|
6
|
-
Author: Andrey Kislyuk
|
7
|
-
Author-email: kislyuk@gmail.com
|
8
|
-
License: Apache Software License
|
9
|
-
Platform: MacOS X
|
10
|
-
Platform: Posix
|
11
|
-
Classifier: Intended Audience :: Developers
|
12
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
13
|
-
Classifier: Operating System :: MacOS :: MacOS X
|
14
|
-
Classifier: Operating System :: POSIX
|
15
|
-
Classifier: Programming Language :: Python
|
16
|
-
Classifier: Programming Language :: Python :: 3.8
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
19
|
-
Classifier: Programming Language :: Python :: 3.11
|
20
|
-
Classifier: Programming Language :: Python :: 3.12
|
21
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
22
|
-
License-File: LICENSE
|
23
|
-
Requires-Dist: http-sfv>=0.9.3
|
24
|
-
Requires-Dist: cryptography>=36.0.2
|
25
|
-
Provides-Extra: tests
|
26
|
-
Requires-Dist: flake8; extra == "tests"
|
27
|
-
Requires-Dist: coverage; extra == "tests"
|
28
|
-
Requires-Dist: build; extra == "tests"
|
29
|
-
Requires-Dist: wheel; extra == "tests"
|
30
|
-
Requires-Dist: mypy; extra == "tests"
|
31
|
-
Requires-Dist: requests; extra == "tests"
|
32
|
-
Requires-Dist: ruff; extra == "tests"
|
33
|
-
|
34
|
-
http-message-signatures: An implementation of RFC 9421, the IETF HTTP Message Signatures standard
|
35
|
-
=================================================================================================
|
36
|
-
|
37
|
-
*http-message-signatures* is an implementation of the IETF
|
38
|
-
`RFC 9421 HTTP Message Signatures <https://datatracker.ietf.org/doc/rfc9421/>`_ draft standard in
|
39
|
-
Python.
|
40
|
-
|
41
|
-
Installation
|
42
|
-
------------
|
43
|
-
::
|
44
|
-
|
45
|
-
pip3 install http-message-signatures
|
46
|
-
|
47
|
-
Synopsis
|
48
|
-
--------
|
49
|
-
|
50
|
-
.. code-block:: python
|
51
|
-
|
52
|
-
from http_message_signatures import HTTPMessageSigner, HTTPMessageVerifier, HTTPSignatureKeyResolver, algorithms
|
53
|
-
import requests, base64, hashlib, http_sfv
|
54
|
-
|
55
|
-
class MyHTTPSignatureKeyResolver(HTTPSignatureKeyResolver):
|
56
|
-
keys = {"my-key": b"top-secret-key"}
|
57
|
-
|
58
|
-
def resolve_public_key(self, key_id: str):
|
59
|
-
return self.keys[key_id]
|
60
|
-
|
61
|
-
def resolve_private_key(self, key_id: str):
|
62
|
-
return self.keys[key_id]
|
63
|
-
|
64
|
-
request = requests.Request('POST', 'https://example.com/foo?param=Value&Pet=dog', json={"hello": "world"})
|
65
|
-
request = request.prepare()
|
66
|
-
request.headers["Content-Digest"] = str(http_sfv.Dictionary({"sha-256": hashlib.sha256(request.body).digest()}))
|
67
|
-
|
68
|
-
signer = HTTPMessageSigner(signature_algorithm=algorithms.HMAC_SHA256, key_resolver=MyHTTPSignatureKeyResolver())
|
69
|
-
signer.sign(request, key_id="my-key", covered_component_ids=("@method", "@authority", "@target-uri", "content-digest"))
|
70
|
-
|
71
|
-
verifier = HTTPMessageVerifier(signature_algorithm=algorithms.HMAC_SHA256, key_resolver=MyHTTPSignatureKeyResolver())
|
72
|
-
verifier.verify(request)
|
73
|
-
|
74
|
-
Note that verifying the body content-digest is outside the scope of this package's functionality, so it remains the
|
75
|
-
caller's responsibility. The `requests-http-signature <https://github.com/pyauth/requests-http-signature>`_ library
|
76
|
-
builds upon this package to provide integrated signing and validation of the request body.
|
77
|
-
|
78
|
-
.. admonition:: See what is signed
|
79
|
-
|
80
|
-
It is important to understand and follow the best practice rule of "See what is signed" when verifying HTTP message
|
81
|
-
signatures. The gist of this rule is: if your application neglects to verify that the information it trusts is
|
82
|
-
what was actually signed, the attacker can supply a valid signature but point you to malicious data that wasn't signed
|
83
|
-
by that signature. Failure to follow this rule can lead to vulnerability against signature wrapping and substitution
|
84
|
-
attacks.
|
85
|
-
|
86
|
-
In http-message-signatures, you can ensure that the information signed is what you expect to be signed by only trusting the
|
87
|
-
data returned by the ``verify()`` method::
|
88
|
-
|
89
|
-
verify_results = verifier.verify(request)
|
90
|
-
|
91
|
-
This returns a list of ``VerifyResult`` s, which are ``namedtuple`` s with the following attributes:
|
92
|
-
|
93
|
-
* label (str): The label for the signature
|
94
|
-
* algorithm: (same as signature_algorithm above)
|
95
|
-
* covered_components: A mapping of component names to their values, as covered by the signature
|
96
|
-
* parameters: A mapping of signature parameters to their values, as covered by the signature
|
97
|
-
* body: Always ``None`` (the `requests-http-signature <https://github.com/pyauth/requests-http-signature>`_ package
|
98
|
-
implements returning the body upon successful digest validation).
|
99
|
-
|
100
|
-
Given an HTTP request can potentially have multiple signatures the ``verify()`` method returns a list of ``VerifyResult`` s.
|
101
|
-
However, the implementation currently supports just one signature, so the returned list currently contains just one element.
|
102
|
-
If more signatures are found in the request then ``InvalidSignature`` is raised.
|
103
|
-
|
104
|
-
Additionally, the ``verify()`` method raises ``HTTPMessageSignaturesException`` or an exception derived from this class in
|
105
|
-
case an error occurs (unable to load PEM key, unsupported algorithm specified in signature input, signature doesn't match
|
106
|
-
digest etc.)
|
107
|
-
|
108
|
-
Authors
|
109
|
-
-------
|
110
|
-
* Andrey Kislyuk
|
111
|
-
|
112
|
-
Links
|
113
|
-
-----
|
114
|
-
* `Project home page (GitHub) <https://github.com/pyauth/http-message-signatures>`_
|
115
|
-
* `Documentation <https://FIXME>`_
|
116
|
-
* `Package distribution (PyPI) <https://pypi.python.org/pypi/http-message-signatures>`_
|
117
|
-
* `Change log <https://github.com/pyauth/http-message-signatures/blob/master/Changes.rst>`_
|
118
|
-
* `IETF HTTP Message Signatures standard tracker <https://datatracker.ietf.org/doc/rfc9421/>`_
|
119
|
-
* `OWASP Top Ten <https://owasp.org/www-project-top-ten/>`_
|
120
|
-
|
121
|
-
Bugs
|
122
|
-
~~~~
|
123
|
-
Please report bugs, issues, feature requests, etc. on `GitHub <https://github.com/pyauth/http-message-signatures/issues>`_.
|
124
|
-
|
125
|
-
License
|
126
|
-
-------
|
127
|
-
Licensed under the terms of the `Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>`_.
|
@@ -1,36 +0,0 @@
|
|
1
|
-
.gitignore
|
2
|
-
Changes.rst
|
3
|
-
LICENSE
|
4
|
-
Makefile
|
5
|
-
README.rst
|
6
|
-
common.mk
|
7
|
-
pyproject.toml
|
8
|
-
setup.cfg
|
9
|
-
setup.py
|
10
|
-
.github/FUNDING.yml
|
11
|
-
.github/workflows/ci.yml
|
12
|
-
docs/conf.py
|
13
|
-
docs/index.rst
|
14
|
-
http_message_signatures/__init__.py
|
15
|
-
http_message_signatures/_algorithms.py
|
16
|
-
http_message_signatures/algorithms.py
|
17
|
-
http_message_signatures/exceptions.py
|
18
|
-
http_message_signatures/py.typed
|
19
|
-
http_message_signatures/resolvers.py
|
20
|
-
http_message_signatures/signatures.py
|
21
|
-
http_message_signatures/structures.py
|
22
|
-
http_message_signatures/version.py
|
23
|
-
http_message_signatures.egg-info/PKG-INFO
|
24
|
-
http_message_signatures.egg-info/SOURCES.txt
|
25
|
-
http_message_signatures.egg-info/dependency_links.txt
|
26
|
-
http_message_signatures.egg-info/requires.txt
|
27
|
-
http_message_signatures.egg-info/top_level.txt
|
28
|
-
test/test-key-ecc-p256.key
|
29
|
-
test/test-key-ecc-p256.pem
|
30
|
-
test/test-key-ed25519.key
|
31
|
-
test/test-key-ed25519.pem
|
32
|
-
test/test-key-rsa-pss.key
|
33
|
-
test/test-key-rsa-pss.pem
|
34
|
-
test/test-key-rsa.key
|
35
|
-
test/test-key-rsa.pem
|
36
|
-
test/test.py
|
@@ -1 +0,0 @@
|
|
1
|
-
|
@@ -1 +0,0 @@
|
|
1
|
-
http_message_signatures
|
@@ -1,49 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
|
3
|
-
from setuptools import find_packages, setup # type: ignore
|
4
|
-
|
5
|
-
setup(
|
6
|
-
name="http-message-signatures",
|
7
|
-
url="https://github.com/pyauth/http-message-signatures",
|
8
|
-
license="Apache Software License",
|
9
|
-
author="Andrey Kislyuk",
|
10
|
-
author_email="kislyuk@gmail.com",
|
11
|
-
description="An implementation of the IETF HTTP Message Signatures draft standard",
|
12
|
-
long_description=open("README.rst").read(),
|
13
|
-
use_scm_version={
|
14
|
-
"write_to": "http_message_signatures/version.py",
|
15
|
-
},
|
16
|
-
setup_requires=["setuptools_scm >= 3.4.3"],
|
17
|
-
install_requires=["http-sfv >= 0.9.3", "cryptography >= 36.0.2"],
|
18
|
-
extras_require={
|
19
|
-
"tests": [
|
20
|
-
"flake8",
|
21
|
-
"coverage",
|
22
|
-
"build",
|
23
|
-
"wheel",
|
24
|
-
"mypy",
|
25
|
-
"requests",
|
26
|
-
"ruff",
|
27
|
-
]
|
28
|
-
},
|
29
|
-
packages=find_packages(exclude=["test"]),
|
30
|
-
include_package_data=True,
|
31
|
-
package_data={
|
32
|
-
"http_message_signatures": ["py.typed"],
|
33
|
-
},
|
34
|
-
platforms=["MacOS X", "Posix"],
|
35
|
-
test_suite="test",
|
36
|
-
classifiers=[
|
37
|
-
"Intended Audience :: Developers",
|
38
|
-
"License :: OSI Approved :: Apache Software License",
|
39
|
-
"Operating System :: MacOS :: MacOS X",
|
40
|
-
"Operating System :: POSIX",
|
41
|
-
"Programming Language :: Python",
|
42
|
-
"Programming Language :: Python :: 3.8",
|
43
|
-
"Programming Language :: Python :: 3.9",
|
44
|
-
"Programming Language :: Python :: 3.10",
|
45
|
-
"Programming Language :: Python :: 3.11",
|
46
|
-
"Programming Language :: Python :: 3.12",
|
47
|
-
"Topic :: Software Development :: Libraries :: Python Modules",
|
48
|
-
],
|
49
|
-
)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/http_message_signatures/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/http_message_signatures/py.typed
RENAMED
File without changes
|
{http-message-signatures-0.5.0 → http_message_signatures-0.6.1}/http_message_signatures/resolvers.py
RENAMED
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
|