mirror of
https://github.com/imayushsaini/Bombsquad-Ballistica-Modded-Server.git
synced 2025-10-20 00:00:39 +00:00
56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
# Released under the MIT License. See LICENSE for details.
|
|
#
|
|
"""Functionality related to verifying ballistica server generated data."""
|
|
|
|
import datetime
|
|
from dataclasses import dataclass
|
|
from typing import TYPE_CHECKING, Annotated
|
|
|
|
from efro.util import utc_now
|
|
from efro.dataclassio import ioprepped, IOAttrs
|
|
|
|
if TYPE_CHECKING:
|
|
pass
|
|
|
|
|
|
@ioprepped
|
|
@dataclass
|
|
class SecureDataChecker:
|
|
"""Verifies data as being signed by our master server."""
|
|
|
|
# Time period this checker is valid for.
|
|
starttime: Annotated[datetime.datetime, IOAttrs('s')]
|
|
endtime: Annotated[datetime.datetime, IOAttrs('e')]
|
|
|
|
# Current set of public keys.
|
|
publickeys: Annotated[list[bytes], IOAttrs('k')]
|
|
|
|
def check(self, data: bytes, signature: bytes) -> bool:
|
|
"""Verify data, returning True if successful.
|
|
|
|
Note that this call imports and uses the cryptography module and
|
|
can be slow; it generally should be done in a background thread
|
|
or on a server.
|
|
"""
|
|
from cryptography.hazmat.primitives.asymmetric import ed25519
|
|
from cryptography.exceptions import InvalidSignature
|
|
|
|
now = utc_now()
|
|
|
|
# Make sure we seem valid based on local time.
|
|
if now < self.starttime:
|
|
raise RuntimeError('SecureDataChecker starttime is in the future.')
|
|
if now > self.endtime:
|
|
raise RuntimeError('SecureDataChecker endtime is in the past.')
|
|
|
|
# Try our keys from newest to oldest. Most stuff will be using
|
|
# the newest key so this should be most efficient.
|
|
for key in reversed(self.publickeys):
|
|
try:
|
|
publickey = ed25519.Ed25519PublicKey.from_public_bytes(key)
|
|
publickey.verify(signature, data)
|
|
return True
|
|
except InvalidSignature:
|
|
pass
|
|
|
|
return False
|