http-message-signatures 0.4.4__py3-none-any.whl → 0.6.1__py3-none-any.whl
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/__init__.py +2 -1
- http_message_signatures/_algorithms.py +17 -19
- http_message_signatures/exceptions.py +1 -1
- http_message_signatures/resolvers.py +3 -3
- http_message_signatures/signatures.py +47 -41
- http_message_signatures/structures.py +1 -5
- {http_message_signatures-0.4.4.dist-info → http_message_signatures-0.6.1.dist-info}/METADATA +41 -24
- http_message_signatures-0.6.1.dist-info/RECORD +13 -0
- {http_message_signatures-0.4.4.dist-info → http_message_signatures-0.6.1.dist-info}/WHEEL +1 -2
- {http_message_signatures-0.4.4.dist-info → http_message_signatures-0.6.1.dist-info/licenses}/LICENSE +0 -24
- http_message_signatures-0.6.1.dist-info/licenses/NOTICE +10 -0
- http_message_signatures/version.py +0 -5
- http_message_signatures-0.4.4.dist-info/RECORD +0 -14
- http_message_signatures-0.4.4.dist-info/top_level.txt +0 -1
@@ -1,6 +1,7 @@
|
|
1
1
|
from . import algorithms # noqa:F401
|
2
2
|
from .algorithms import HTTPSignatureAlgorithm # noqa:F401
|
3
3
|
from .exceptions import HTTPMessageSignaturesException, InvalidSignature # noqa:F401
|
4
|
-
from .resolvers import HTTPSignatureComponentResolver
|
4
|
+
from .resolvers import HTTPSignatureComponentResolver # noqa:F401
|
5
|
+
from .resolvers import HTTPSignatureKeyResolver # noqa: F401
|
5
6
|
from .signatures import HTTPMessageSigner, HTTPMessageVerifier # noqa:F401
|
6
7
|
from .structures import VerifyResult # noqa:F401
|
@@ -1,7 +1,13 @@
|
|
1
1
|
from cryptography.hazmat.primitives import hashes, hmac
|
2
2
|
from cryptography.hazmat.primitives.asymmetric import ec, ed25519, padding, rsa
|
3
|
-
from cryptography.hazmat.primitives.asymmetric.utils import
|
4
|
-
|
3
|
+
from cryptography.hazmat.primitives.asymmetric.utils import (
|
4
|
+
decode_dss_signature,
|
5
|
+
encode_dss_signature,
|
6
|
+
)
|
7
|
+
from cryptography.hazmat.primitives.serialization import (
|
8
|
+
load_pem_private_key,
|
9
|
+
load_pem_public_key,
|
10
|
+
)
|
5
11
|
|
6
12
|
from .exceptions import HTTPMessageSignaturesException
|
7
13
|
|
@@ -41,15 +47,10 @@ class RSA_PSS_SHA512(HTTPSignatureAlgorithm, PEMKeyLoader):
|
|
41
47
|
self.hash_algorithm: hashes.HashAlgorithm = hashes.SHA512()
|
42
48
|
|
43
49
|
def sign(self, message: bytes):
|
44
|
-
return self.private_key.sign(data=message,
|
45
|
-
padding=self.padding,
|
46
|
-
algorithm=self.hash_algorithm)
|
50
|
+
return self.private_key.sign(data=message, padding=self.padding, algorithm=self.hash_algorithm)
|
47
51
|
|
48
52
|
def verify(self, signature: bytes, message: bytes):
|
49
|
-
self.public_key.verify(signature=signature,
|
50
|
-
data=message,
|
51
|
-
padding=self.padding,
|
52
|
-
algorithm=self.hash_algorithm)
|
53
|
+
self.public_key.verify(signature=signature, data=message, padding=self.padding, algorithm=self.hash_algorithm)
|
53
54
|
|
54
55
|
|
55
56
|
class RSA_V1_5_SHA256(RSA_PSS_SHA512):
|
@@ -90,27 +91,24 @@ class ECDSA_P256_SHA256(HTTPSignatureAlgorithm, PEMKeyLoader):
|
|
90
91
|
raise HTTPMessageSignaturesException("Unexpected public key type")
|
91
92
|
if self.private_key and not isinstance(self.private_key, ec.EllipticCurvePrivateKey):
|
92
93
|
raise HTTPMessageSignaturesException("Unexpected private key type")
|
93
|
-
if self.public_key and
|
94
|
+
if self.public_key and not isinstance(self.public_key.curve, ec.SECP256R1):
|
94
95
|
raise HTTPMessageSignaturesException("Unexpected elliptic curve type in public key")
|
95
|
-
if self.private_key and
|
96
|
+
if self.private_key and not isinstance(self.private_key.curve, ec.SECP256R1):
|
96
97
|
raise HTTPMessageSignaturesException("Unexpected elliptic curve type in private key")
|
97
98
|
self.signature_algorithm = ec.ECDSA(hashes.SHA256())
|
98
99
|
|
99
100
|
def sign(self, message: bytes):
|
100
|
-
der_sig = self.private_key.sign(message,
|
101
|
-
signature_algorithm=self.signature_algorithm)
|
101
|
+
der_sig = self.private_key.sign(message, signature_algorithm=self.signature_algorithm)
|
102
102
|
r, s = decode_dss_signature(der_sig)
|
103
|
-
return r.to_bytes(32, byteorder=
|
103
|
+
return r.to_bytes(32, byteorder="big") + s.to_bytes(32, byteorder="big")
|
104
104
|
|
105
105
|
def verify(self, signature: bytes, message: bytes):
|
106
106
|
if len(signature) != 64:
|
107
107
|
raise HTTPMessageSignaturesException("Unexpected signature length")
|
108
|
-
r = int.from_bytes(signature[:32], byteorder=
|
109
|
-
s = int.from_bytes(signature[32:], byteorder=
|
108
|
+
r = int.from_bytes(signature[:32], byteorder="big")
|
109
|
+
s = int.from_bytes(signature[32:], byteorder="big")
|
110
110
|
der_sig = encode_dss_signature(r, s)
|
111
|
-
self.public_key.verify(signature=der_sig,
|
112
|
-
data=message,
|
113
|
-
signature_algorithm=self.signature_algorithm)
|
111
|
+
self.public_key.verify(signature=der_sig, data=message, signature_algorithm=self.signature_algorithm)
|
114
112
|
|
115
113
|
|
116
114
|
class ED25519(HTTPSignatureAlgorithm, PEMKeyLoader):
|
@@ -2,5 +2,5 @@ class HTTPMessageSignaturesException(Exception):
|
|
2
2
|
"Base class for exceptions raised by http_message_signatures"
|
3
3
|
|
4
4
|
|
5
|
-
class InvalidSignature(
|
5
|
+
class InvalidSignature(HTTPMessageSignaturesException):
|
6
6
|
"Class for exceptions raised in the course of verifying an HTTP message signature"
|
@@ -17,7 +17,7 @@ class HTTPSignatureComponentResolver:
|
|
17
17
|
"@query",
|
18
18
|
"@query-params",
|
19
19
|
"@status",
|
20
|
-
"@request-response"
|
20
|
+
"@request-response",
|
21
21
|
}
|
22
22
|
|
23
23
|
# TODO: describe interface
|
@@ -33,7 +33,7 @@ class HTTPSignatureComponentResolver:
|
|
33
33
|
component_id = str(component_node.value)
|
34
34
|
if component_id.startswith("@"): # derived component
|
35
35
|
if component_id not in self.derived_component_names:
|
36
|
-
raise HTTPMessageSignaturesException(f
|
36
|
+
raise HTTPMessageSignaturesException(f"Unknown covered derived component name {component_id}")
|
37
37
|
resolver = getattr(self, "get_" + component_id[1:].replace("-", "_"))
|
38
38
|
return resolver(**component_node.params)
|
39
39
|
if component_id not in self.headers:
|
@@ -68,7 +68,7 @@ class HTTPSignatureComponentResolver:
|
|
68
68
|
if name not in query:
|
69
69
|
raise HTTPMessageSignaturesException(f'Query parameter "{name}" not found in the message URL')
|
70
70
|
if len(query[name]) != 1:
|
71
|
-
raise HTTPMessageSignaturesException(
|
71
|
+
raise HTTPMessageSignaturesException("Query parameters with multiple values are not supported.")
|
72
72
|
return query[name][0]
|
73
73
|
|
74
74
|
def get_status(self):
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import collections
|
2
2
|
import datetime
|
3
3
|
import logging
|
4
|
-
from typing import Any, Dict, List, Sequence, Tuple, Type
|
4
|
+
from typing import Any, Dict, List, Optional, Sequence, Tuple, Type
|
5
5
|
|
6
6
|
import http_sfv
|
7
7
|
|
@@ -14,27 +14,24 @@ logger = logging.getLogger(__name__)
|
|
14
14
|
|
15
15
|
|
16
16
|
class HTTPSignatureHandler:
|
17
|
-
signature_metadata_parameters = {
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
signature_algorithm: Type[HTTPSignatureAlgorithm],
|
27
|
-
key_resolver: HTTPSignatureKeyResolver,
|
28
|
-
component_resolver_class: type = HTTPSignatureComponentResolver):
|
17
|
+
signature_metadata_parameters = {"alg", "created", "expires", "keyid", "nonce", "tag"}
|
18
|
+
|
19
|
+
def __init__(
|
20
|
+
self,
|
21
|
+
*,
|
22
|
+
signature_algorithm: Type[HTTPSignatureAlgorithm],
|
23
|
+
key_resolver: HTTPSignatureKeyResolver,
|
24
|
+
component_resolver_class: type = HTTPSignatureComponentResolver,
|
25
|
+
):
|
29
26
|
if signature_algorithm not in signature_algorithms.values():
|
30
27
|
raise HTTPMessageSignaturesException(f"Unknown signature algorithm {signature_algorithm}")
|
31
28
|
self.signature_algorithm = signature_algorithm
|
32
29
|
self.key_resolver = key_resolver
|
33
30
|
self.component_resolver_class = component_resolver_class
|
34
31
|
|
35
|
-
def _build_signature_base(
|
36
|
-
|
37
|
-
|
32
|
+
def _build_signature_base(
|
33
|
+
self, message, *, covered_component_ids: List[Any], signature_params: Dict[str, str]
|
34
|
+
) -> Tuple:
|
38
35
|
assert "@signature-params" not in covered_component_ids
|
39
36
|
sig_elements = collections.OrderedDict()
|
40
37
|
component_resolver = self.component_resolver_class(message)
|
@@ -48,8 +45,9 @@ class HTTPSignatureHandler:
|
|
48
45
|
if "\n" in component_key:
|
49
46
|
raise HTTPMessageSignaturesException(f'Component ID "{component_key}" contains newline character')
|
50
47
|
if component_key in sig_elements:
|
51
|
-
raise HTTPMessageSignaturesException(
|
52
|
-
|
48
|
+
raise HTTPMessageSignaturesException(
|
49
|
+
f'Component ID "{component_key}" appeared multiple times in signature input'
|
50
|
+
)
|
53
51
|
sig_elements[component_key] = component_value
|
54
52
|
sig_params_node = http_sfv.InnerList(covered_component_ids)
|
55
53
|
sig_params_node.params.update(signature_params)
|
@@ -72,14 +70,19 @@ class HTTPMessageSigner(HTTPSignatureHandler):
|
|
72
70
|
covered_component_nodes.append(component_name_node)
|
73
71
|
return covered_component_nodes
|
74
72
|
|
75
|
-
def sign(
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
73
|
+
def sign(
|
74
|
+
self,
|
75
|
+
message,
|
76
|
+
*,
|
77
|
+
key_id: str,
|
78
|
+
created: Optional[datetime.datetime] = None,
|
79
|
+
expires: Optional[datetime.datetime] = None,
|
80
|
+
nonce: Optional[str] = None,
|
81
|
+
label: Optional[str] = None,
|
82
|
+
tag: Optional[str] = None,
|
83
|
+
include_alg: bool = True,
|
84
|
+
covered_component_ids: Sequence[str] = ("@method", "@authority", "@target-uri"),
|
85
|
+
):
|
83
86
|
# TODO: Accept-Signature autonegotiation
|
84
87
|
key = self.key_resolver.resolve_private_key(key_id)
|
85
88
|
if created is None:
|
@@ -91,13 +94,13 @@ class HTTPMessageSigner(HTTPSignatureHandler):
|
|
91
94
|
signature_params["expires"] = int(expires.timestamp())
|
92
95
|
if nonce:
|
93
96
|
signature_params["nonce"] = nonce
|
97
|
+
if tag:
|
98
|
+
signature_params["tag"] = tag
|
94
99
|
if include_alg:
|
95
100
|
signature_params["alg"] = self.signature_algorithm.algorithm_id
|
96
101
|
covered_component_nodes = self._parse_covered_component_ids(covered_component_ids)
|
97
102
|
sig_base, sig_params_node, _ = self._build_signature_base(
|
98
|
-
message,
|
99
|
-
covered_component_ids=covered_component_nodes,
|
100
|
-
signature_params=signature_params
|
103
|
+
message, covered_component_ids=covered_component_nodes, signature_params=signature_params
|
101
104
|
)
|
102
105
|
signer = self.signature_algorithm(private_key=key)
|
103
106
|
signature = signer.sign(sig_base.encode())
|
@@ -111,6 +114,7 @@ class HTTPMessageSigner(HTTPSignatureHandler):
|
|
111
114
|
|
112
115
|
|
113
116
|
class HTTPMessageVerifier(HTTPSignatureHandler):
|
117
|
+
max_clock_skew: datetime.timedelta = datetime.timedelta(seconds=5)
|
114
118
|
require_created: bool = True
|
115
119
|
|
116
120
|
def _parse_dict_header(self, header_name, headers):
|
@@ -133,17 +137,19 @@ class HTTPMessageVerifier(HTTPSignatureHandler):
|
|
133
137
|
|
134
138
|
def validate_created_and_expires(self, sig_input, max_age=None):
|
135
139
|
now = datetime.datetime.now()
|
140
|
+
min_time = now - self.max_clock_skew
|
141
|
+
max_time = now + self.max_clock_skew
|
136
142
|
if "created" in sig_input.params:
|
137
|
-
if self._parse_integer_timestamp(sig_input.params["created"], field_name="created") >
|
143
|
+
if self._parse_integer_timestamp(sig_input.params["created"], field_name="created") > max_time:
|
138
144
|
raise InvalidSignature('Signature "created" parameter is set to a time in the future')
|
139
145
|
elif self.require_created:
|
140
146
|
raise InvalidSignature('Signature is missing a required "created" parameter')
|
141
147
|
if "expires" in sig_input.params:
|
142
|
-
if self._parse_integer_timestamp(sig_input.params["expires"], field_name="expires") <
|
148
|
+
if self._parse_integer_timestamp(sig_input.params["expires"], field_name="expires") < min_time:
|
143
149
|
raise InvalidSignature('Signature "expires" parameter is set to a time in the past')
|
144
150
|
if max_age is not None:
|
145
|
-
if self._parse_integer_timestamp(sig_input.params["created"], field_name="created") + max_age <
|
146
|
-
raise InvalidSignature(f
|
151
|
+
if self._parse_integer_timestamp(sig_input.params["created"], field_name="created") + max_age < min_time:
|
152
|
+
raise InvalidSignature(f"Signature age exceeds maximum allowable age {max_age}")
|
147
153
|
|
148
154
|
def verify(self, message, *, max_age: datetime.timedelta = datetime.timedelta(days=1)) -> List[VerifyResult]:
|
149
155
|
sig_inputs = self._parse_dict_header("Signature-Input", message.headers)
|
@@ -165,9 +171,7 @@ class HTTPMessageVerifier(HTTPSignatureHandler):
|
|
165
171
|
raise InvalidSignature(f'Unexpected signature metadata parameter "{param}"')
|
166
172
|
try:
|
167
173
|
sig_base, sig_params_node, sig_elements = self._build_signature_base(
|
168
|
-
message,
|
169
|
-
covered_component_ids=list(sig_input),
|
170
|
-
signature_params=sig_input.params
|
174
|
+
message, covered_component_ids=list(sig_input), signature_params=sig_input.params
|
171
175
|
)
|
172
176
|
except Exception as e:
|
173
177
|
raise InvalidSignature(e) from e
|
@@ -177,10 +181,12 @@ class HTTPMessageVerifier(HTTPSignatureHandler):
|
|
177
181
|
verifier.verify(signature=raw_signature, message=sig_base.encode())
|
178
182
|
except Exception as e:
|
179
183
|
raise InvalidSignature(e) from e
|
180
|
-
verify_result = VerifyResult(
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
184
|
+
verify_result = VerifyResult(
|
185
|
+
label=label,
|
186
|
+
algorithm=self.signature_algorithm,
|
187
|
+
covered_components=sig_elements,
|
188
|
+
parameters=dict(sig_params_node.params),
|
189
|
+
body=None,
|
190
|
+
)
|
185
191
|
verify_results.append(verify_result)
|
186
192
|
return verify_results
|
@@ -34,11 +34,7 @@ class CaseInsensitiveDict(MutableMapping):
|
|
34
34
|
|
35
35
|
def lower_items(self):
|
36
36
|
"""Like iteritems(), but with all lowercase keys."""
|
37
|
-
return (
|
38
|
-
(lowerkey, keyval[1])
|
39
|
-
for (lowerkey, keyval)
|
40
|
-
in self._store.items()
|
41
|
-
)
|
37
|
+
return ((lowerkey, keyval[1]) for (lowerkey, keyval) in self._store.items())
|
42
38
|
|
43
39
|
def __eq__(self, other):
|
44
40
|
if isinstance(other, Mapping):
|
{http_message_signatures-0.4.4.dist-info → http_message_signatures-0.6.1.dist-info}/METADATA
RENAMED
@@ -1,39 +1,45 @@
|
|
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
|
14
16
|
Classifier: Operating System :: POSIX
|
15
17
|
Classifier: Programming Language :: Python
|
16
|
-
Classifier: Programming Language :: Python :: 3.7
|
17
18
|
Classifier: Programming Language :: Python :: 3.8
|
18
19
|
Classifier: Programming Language :: Python :: 3.9
|
19
20
|
Classifier: Programming Language :: Python :: 3.10
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
20
24
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
21
|
-
|
22
|
-
Requires-Dist:
|
23
|
-
Requires-Dist:
|
25
|
+
Requires-Python: >=3.8
|
26
|
+
Requires-Dist: cryptography>=36.0.2
|
27
|
+
Requires-Dist: http-sfv>=0.9.3
|
24
28
|
Provides-Extra: tests
|
25
|
-
Requires-Dist:
|
26
|
-
Requires-Dist: coverage
|
27
|
-
Requires-Dist:
|
28
|
-
Requires-Dist:
|
29
|
-
Requires-Dist:
|
30
|
-
Requires-Dist:
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
37
|
+
|
38
|
+
http-message-signatures: An implementation of RFC 9421, the IETF HTTP Message Signatures standard
|
39
|
+
=================================================================================================
|
34
40
|
|
35
41
|
*http-message-signatures* is an implementation of the IETF
|
36
|
-
`HTTP Message Signatures <https://datatracker.ietf.org/doc/
|
42
|
+
`RFC 9421 HTTP Message Signatures <https://datatracker.ietf.org/doc/rfc9421/>`_ standard in
|
37
43
|
Python.
|
38
44
|
|
39
45
|
Installation
|
@@ -84,9 +90,9 @@ builds upon this package to provide integrated signing and validation of the req
|
|
84
90
|
In http-message-signatures, you can ensure that the information signed is what you expect to be signed by only trusting the
|
85
91
|
data returned by the ``verify()`` method::
|
86
92
|
|
87
|
-
|
93
|
+
verify_results = verifier.verify(request)
|
88
94
|
|
89
|
-
This returns VerifyResult,
|
95
|
+
This returns a list of ``VerifyResult`` s, which are ``namedtuple`` s with the following attributes:
|
90
96
|
|
91
97
|
* label (str): The label for the signature
|
92
98
|
* algorithm: (same as signature_algorithm above)
|
@@ -95,9 +101,17 @@ builds upon this package to provide integrated signing and validation of the req
|
|
95
101
|
* body: Always ``None`` (the `requests-http-signature <https://github.com/pyauth/requests-http-signature>`_ package
|
96
102
|
implements returning the body upon successful digest validation).
|
97
103
|
|
104
|
+
Given an HTTP request can potentially have multiple signatures the ``verify()`` method returns a list of ``VerifyResult`` s.
|
105
|
+
However, the implementation currently supports just one signature, so the returned list currently contains just one element.
|
106
|
+
If more signatures are found in the request then ``InvalidSignature`` is raised.
|
107
|
+
|
108
|
+
Additionally, the ``verify()`` method raises ``HTTPMessageSignaturesException`` or an exception derived from this class in
|
109
|
+
case an error occurs (unable to load PEM key, unsupported algorithm specified in signature input, signature doesn't match
|
110
|
+
digest etc.)
|
111
|
+
|
98
112
|
Authors
|
99
113
|
-------
|
100
|
-
* Andrey Kislyuk
|
114
|
+
* `Andrey Kislyuk <https://kislyuk.com>`
|
101
115
|
|
102
116
|
Links
|
103
117
|
-----
|
@@ -105,7 +119,7 @@ Links
|
|
105
119
|
* `Documentation <https://FIXME>`_
|
106
120
|
* `Package distribution (PyPI) <https://pypi.python.org/pypi/http-message-signatures>`_
|
107
121
|
* `Change log <https://github.com/pyauth/http-message-signatures/blob/master/Changes.rst>`_
|
108
|
-
* `IETF HTTP Message Signatures standard tracker <https://datatracker.ietf.org/doc/
|
122
|
+
* `IETF HTTP Message Signatures standard tracker <https://datatracker.ietf.org/doc/rfc9421/>`_
|
109
123
|
* `OWASP Top Ten <https://owasp.org/www-project-top-ten/>`_
|
110
124
|
|
111
125
|
Bugs
|
@@ -114,4 +128,7 @@ Please report bugs, issues, feature requests, etc. on `GitHub <https://github.co
|
|
114
128
|
|
115
129
|
License
|
116
130
|
-------
|
117
|
-
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.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
http_message_signatures/__init__.py,sha256=uGQgs5h8d16QPBbquDHzgD0SC1vF-Y8vXFWQtDHw3PE,439
|
2
|
+
http_message_signatures/_algorithms.py,sha256=XW1yajZqG8XmL_SaoWSp_ya-yfENCBt7A3F02Yf3ZXg,6468
|
3
|
+
http_message_signatures/algorithms.py,sha256=CXHOcleb8dkdTSUxTdNfl-d0XkVxSXGmf9ugKe_xGaY,190
|
4
|
+
http_message_signatures/exceptions.py,sha256=kEF1-8-ACSQL97vfIo_bwv-Hh8pdtjXjRDbsrFKlgA4,260
|
5
|
+
http_message_signatures/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
+
http_message_signatures/resolvers.py,sha256=h-kdnS1Ie3Xv5z22GrE_HkAHHONJ66W3kkEbReGLGLE,3260
|
7
|
+
http_message_signatures/signatures.py,sha256=BXFGNYcq4zPDkmfZ7WSKT-MhxMZB3acpiapJEzX-zTg,9286
|
8
|
+
http_message_signatures/structures.py,sha256=xCz9W4Rmjj541GgGdjZeKNObxLFqN8mdZFrsOg9g9Yc,1575
|
9
|
+
http_message_signatures-0.6.1.dist-info/METADATA,sha256=L7g_TK27F6mzY9A3KokxKIERXS15sPLFL3BK6H4GLY8,6293
|
10
|
+
http_message_signatures-0.6.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
11
|
+
http_message_signatures-0.6.1.dist-info/licenses/LICENSE,sha256=h-3wDrOtt7Mou9MC2Hz07aB0PwvDbGAYnVLAXlFqBAI,9144
|
12
|
+
http_message_signatures-0.6.1.dist-info/licenses/NOTICE,sha256=uffnI3KUzenxf-zvcOBEIbaShnRk1fMnvgSzdy1C2M0,634
|
13
|
+
http_message_signatures-0.6.1.dist-info/RECORD,,
|
{http_message_signatures-0.4.4.dist-info → http_message_signatures-0.6.1.dist-info/licenses}/LICENSE
RENAMED
@@ -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,14 +0,0 @@
|
|
1
|
-
http_message_signatures/__init__.py,sha256=5rr1v-1D3KLtFNtdEc-XmqxBeAhSBb0LOEzF8cTHpqY,403
|
2
|
-
http_message_signatures/_algorithms.py,sha256=xSjvOhHq0vKxj7pC_Li9E9cppjXahDkiwTf2c2BGZ_I,6695
|
3
|
-
http_message_signatures/algorithms.py,sha256=CXHOcleb8dkdTSUxTdNfl-d0XkVxSXGmf9ugKe_xGaY,190
|
4
|
-
http_message_signatures/exceptions.py,sha256=lbIJ5Z2feWFKhH2C4knI4bi0mhYB-jmi__ZV-iNIgHI,239
|
5
|
-
http_message_signatures/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
-
http_message_signatures/resolvers.py,sha256=9FpzLWwm7kRtdN8Eo92YJnT936Y61cmHBf2bmY0w_ns,3259
|
7
|
-
http_message_signatures/signatures.py,sha256=jfAGmeuAmQOlLSt-aTLN41_D9V9lo2xCSomPvLaCwno,9211
|
8
|
-
http_message_signatures/structures.py,sha256=BD1JYI7SX_H80KNY7zfWFfCpNQarkbOGz3_JL0H9p2w,1621
|
9
|
-
http_message_signatures/version.py,sha256=W0kYbjRAk8XX-ioVH2wF3kiQ-6mGnmLLhxzsLZbREb8,176
|
10
|
-
http_message_signatures-0.4.4.dist-info/LICENSE,sha256=c7p036pSC0mkAbXSFFmoUjoUbzt1GKgz7qXvqFEwv2g,10273
|
11
|
-
http_message_signatures-0.4.4.dist-info/METADATA,sha256=QGzFUEthWqx2KI25e__C1Mm-8mXIf-0Qx_cUE0tny6Y,5192
|
12
|
-
http_message_signatures-0.4.4.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
13
|
-
http_message_signatures-0.4.4.dist-info/top_level.txt,sha256=9-VThl-09OI1yQ1ejs76InY3ENi24isY60cUUZrviiw,24
|
14
|
-
http_message_signatures-0.4.4.dist-info/RECORD,,
|
@@ -1 +0,0 @@
|
|
1
|
-
http_message_signatures
|