mms-client 1.0.5__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.
- mms_client/__init__.py +0 -0
- mms_client/client.py +14 -0
- mms_client/py.typed +0 -0
- mms_client/schemas/wsdl/mi-web-service-jbms.wsdl +276 -0
- mms_client/schemas/wsdl/omi-web-service.wsdl +262 -0
- mms_client/schemas/xsd/mi-market.xsd +2395 -0
- mms_client/schemas/xsd/mi-outbnd-reports.xsd +1489 -0
- mms_client/schemas/xsd/mi-report.xsd +379 -0
- mms_client/schemas/xsd/mpr.xsd +1817 -0
- mms_client/schemas/xsd/omi.xsd +793 -0
- mms_client/security/__init__.py +0 -0
- mms_client/security/certs.py +44 -0
- mms_client/security/crypto.py +57 -0
- mms_client/services/__init__.py +0 -0
- mms_client/services/base.py +591 -0
- mms_client/services/market.py +107 -0
- mms_client/services/omi.py +13 -0
- mms_client/services/registration.py +13 -0
- mms_client/services/report.py +13 -0
- mms_client/types/__init__.py +0 -0
- mms_client/types/base.py +272 -0
- mms_client/types/enums.py +18 -0
- mms_client/types/fields.py +153 -0
- mms_client/types/market.py +61 -0
- mms_client/types/offer.py +163 -0
- mms_client/types/transport.py +130 -0
- mms_client/utils/__init__.py +0 -0
- mms_client/utils/errors.py +66 -0
- mms_client/utils/serialization.py +513 -0
- mms_client/utils/web.py +220 -0
- mms_client-1.0.5.dist-info/LICENSE +24 -0
- mms_client-1.0.5.dist-info/METADATA +202 -0
- mms_client-1.0.5.dist-info/RECORD +34 -0
- mms_client-1.0.5.dist-info/WHEEL +4 -0
|
File without changes
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Contains functionality associated with certificates."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Union
|
|
5
|
+
|
|
6
|
+
from requests_pkcs12 import Pkcs12Adapter
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Certificate:
|
|
10
|
+
"""Describes a certificate composed of a cert file and a key file."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, cert: Union[str, Path, bytes], passphrase: str):
|
|
13
|
+
"""Create a new Certificate.
|
|
14
|
+
|
|
15
|
+
Creates a new certificate from the absolute path to the certificate file and a passpharse.
|
|
16
|
+
|
|
17
|
+
Arguments:
|
|
18
|
+
cert: The certificate file. If a string, it should be the absolute path to the certificate file. If
|
|
19
|
+
bytes, it should be the contents of the certificate file.
|
|
20
|
+
passphrase: The passphrase the certificate is encrypted with
|
|
21
|
+
"""
|
|
22
|
+
# Get the certificate file contents
|
|
23
|
+
if isinstance(cert, (str, Path)):
|
|
24
|
+
with open(cert, "rb") as file:
|
|
25
|
+
self._cert = file.read()
|
|
26
|
+
else:
|
|
27
|
+
self._cert = cert
|
|
28
|
+
|
|
29
|
+
# Save the passphrase
|
|
30
|
+
self._passphrase = passphrase
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def certificate(self) -> bytes:
|
|
34
|
+
"""Return the certificate data."""
|
|
35
|
+
return self._cert
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def passphrase(self) -> str:
|
|
39
|
+
"""Return the full path to the passphrase."""
|
|
40
|
+
return self._passphrase
|
|
41
|
+
|
|
42
|
+
def to_adapter(self) -> Pkcs12Adapter:
|
|
43
|
+
"""Convert the certificate to a Pkcs12Adapter."""
|
|
44
|
+
return Pkcs12Adapter(pkcs12_data=self._cert, pkcs12_password=self._passphrase)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Contains objects for cryptographic operations."""
|
|
2
|
+
|
|
3
|
+
from base64 import b64encode
|
|
4
|
+
from hashlib import sha256
|
|
5
|
+
|
|
6
|
+
from cryptography.hazmat.backends import default_backend
|
|
7
|
+
from cryptography.hazmat.primitives import hashes
|
|
8
|
+
from cryptography.hazmat.primitives.asymmetric import padding
|
|
9
|
+
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
|
|
10
|
+
from cryptography.hazmat.primitives.serialization.pkcs12 import load_key_and_certificates
|
|
11
|
+
|
|
12
|
+
from mms_client.security.certs import Certificate
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CryptoWrapper:
|
|
16
|
+
"""Wraps the cryptographic operations necessary for signing and encrypting MMS payload data."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, cert: Certificate):
|
|
19
|
+
"""Create a new CryptoWrapper with the given certificate.
|
|
20
|
+
|
|
21
|
+
Arguments:
|
|
22
|
+
cert (Certificate): The certificate to use for cryptographic operations.
|
|
23
|
+
"""
|
|
24
|
+
# First, save our certificate for later use
|
|
25
|
+
self._cert = cert
|
|
26
|
+
|
|
27
|
+
# Next, import the private key from the certificate
|
|
28
|
+
private_key, _, _ = load_key_and_certificates(
|
|
29
|
+
self._cert.certificate, self._cert.passphrase.encode(), default_backend()
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Now, we need to assert typing on this private key to make mypy happy
|
|
33
|
+
if isinstance(private_key, RSAPrivateKey):
|
|
34
|
+
self._private_key = private_key
|
|
35
|
+
else:
|
|
36
|
+
raise TypeError(f"Private key of type ({type(private_key).__name__}) was not expected.")
|
|
37
|
+
|
|
38
|
+
# Finally, save our padding and algorithm for later use
|
|
39
|
+
self._padding = padding.PKCS1v15()
|
|
40
|
+
self._algorithm = hashes.SHA256()
|
|
41
|
+
|
|
42
|
+
def sign(self, data: bytes) -> bytes:
|
|
43
|
+
"""Create a signature from the given data using the certificate.
|
|
44
|
+
|
|
45
|
+
Arguments:
|
|
46
|
+
data (bytes): The data to be encrypted.
|
|
47
|
+
|
|
48
|
+
Returns: A base64-encoded string containing the signature.
|
|
49
|
+
"""
|
|
50
|
+
# First, hash the data using SHA256
|
|
51
|
+
hashed = sha256(data)
|
|
52
|
+
|
|
53
|
+
# Next, sign the hash using the private key
|
|
54
|
+
signature = self._private_key.sign(hashed.digest(), self._padding, self._algorithm)
|
|
55
|
+
|
|
56
|
+
# Finally, return the base64-encoded signature
|
|
57
|
+
return b64encode(signature)
|
|
File without changes
|