2022-01-06 17:36:46 +00:00
|
|
|
"""
|
|
|
|
Common HTTP infrastructure for the storge server.
|
|
|
|
"""
|
|
|
|
|
|
|
|
from enum import Enum
|
2022-04-06 13:37:18 +00:00
|
|
|
from base64 import urlsafe_b64encode, b64encode
|
2022-03-02 15:35:41 +00:00
|
|
|
from hashlib import sha256
|
2022-03-14 15:09:40 +00:00
|
|
|
from typing import Optional
|
2022-03-02 15:35:41 +00:00
|
|
|
|
|
|
|
from cryptography.x509 import Certificate
|
|
|
|
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
|
2022-01-06 17:36:46 +00:00
|
|
|
|
2022-03-14 15:09:40 +00:00
|
|
|
from werkzeug.http import parse_options_header
|
|
|
|
from twisted.web.http_headers import Headers
|
|
|
|
|
2022-03-14 15:18:53 +00:00
|
|
|
CBOR_MIME_TYPE = "application/cbor"
|
|
|
|
|
2022-03-14 15:09:40 +00:00
|
|
|
|
|
|
|
def get_content_type(headers: Headers) -> Optional[str]:
|
|
|
|
"""
|
|
|
|
Get the content type from the HTTP ``Content-Type`` header.
|
|
|
|
|
|
|
|
Returns ``None`` if no content-type was set.
|
|
|
|
"""
|
|
|
|
values = headers.getRawHeaders("content-type") or [None]
|
|
|
|
content_type = parse_options_header(values[0])[0] or None
|
|
|
|
return content_type
|
2022-01-06 17:36:46 +00:00
|
|
|
|
|
|
|
|
2022-04-14 15:45:47 +00:00
|
|
|
def swissnum_auth_header(swissnum: bytes) -> bytes:
|
2022-01-06 17:36:46 +00:00
|
|
|
"""Return value for ``Authentication`` header."""
|
|
|
|
return b"Tahoe-LAFS " + b64encode(swissnum).strip()
|
|
|
|
|
|
|
|
|
|
|
|
class Secrets(Enum):
|
|
|
|
"""Different kinds of secrets the client may send."""
|
|
|
|
|
|
|
|
LEASE_RENEW = "lease-renew-secret"
|
|
|
|
LEASE_CANCEL = "lease-cancel-secret"
|
|
|
|
UPLOAD = "upload-secret"
|
2022-04-15 13:08:16 +00:00
|
|
|
WRITE_ENABLER = "write-enabler"
|
2022-03-02 15:35:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_spki_hash(certificate: Certificate) -> bytes:
|
|
|
|
"""
|
|
|
|
Get the public key hash, as per RFC 7469: base64 of sha256 of the public
|
|
|
|
key encoded in DER + Subject Public Key Info format.
|
2022-04-06 13:37:18 +00:00
|
|
|
|
|
|
|
We use the URL-safe base64 variant, since this is typically found in NURLs.
|
2022-03-02 15:35:41 +00:00
|
|
|
"""
|
|
|
|
public_key_bytes = certificate.public_key().public_bytes(
|
|
|
|
Encoding.DER, PublicFormat.SubjectPublicKeyInfo
|
|
|
|
)
|
2022-04-06 13:37:18 +00:00
|
|
|
return urlsafe_b64encode(sha256(public_key_bytes).digest()).strip().rstrip(b"=")
|