maleo-foundation 0.1.70__py3-none-any.whl → 0.1.72__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.
- maleo_foundation/client/services/signature.py +17 -20
- maleo_foundation/client/services/token.py +32 -4
- maleo_foundation/managers/client/base.py +12 -1
- maleo_foundation/middlewares/authentication.py +13 -1
- maleo_foundation/utils/loaders/__init__.py +2 -2
- maleo_foundation/utils/loaders/key/__init__.py +5 -0
- maleo_foundation/utils/loaders/key/rsa.py +93 -0
- {maleo_foundation-0.1.70.dist-info → maleo_foundation-0.1.72.dist-info}/METADATA +1 -1
- {maleo_foundation-0.1.70.dist-info → maleo_foundation-0.1.72.dist-info}/RECORD +11 -10
- maleo_foundation/utils/loaders/key.py +0 -67
- {maleo_foundation-0.1.70.dist-info → maleo_foundation-0.1.72.dist-info}/WHEEL +0 -0
- {maleo_foundation-0.1.70.dist-info → maleo_foundation-0.1.72.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,14 @@
|
|
1
1
|
from base64 import b64decode, b64encode
|
2
|
-
from Crypto.PublicKey import RSA
|
3
2
|
from Crypto.Hash import SHA256
|
4
3
|
from Crypto.Signature import pkcs1_15
|
4
|
+
from maleo_foundation.enums import BaseEnums
|
5
|
+
from maleo_foundation.expanded_types.signature import BaseSignatureResultsTypes
|
6
|
+
from maleo_foundation.managers.client.base import ClientService
|
5
7
|
from maleo_foundation.models.schemas.signature import BaseSignatureSchemas
|
6
8
|
from maleo_foundation.models.transfers.parameters.signature import BaseSignatureParametersTransfers
|
7
9
|
from maleo_foundation.models.transfers.results.signature import BaseSignatureResultsTransfers
|
8
|
-
from maleo_foundation.expanded_types.signature import BaseSignatureResultsTypes
|
9
|
-
from maleo_foundation.managers.client.base import ClientService
|
10
10
|
from maleo_foundation.utils.exceptions import BaseExceptions
|
11
|
+
from maleo_foundation.utils.loaders.key.rsa import RSAKeyLoader
|
11
12
|
|
12
13
|
class MaleoFoundationSignatureClientService(ClientService):
|
13
14
|
def sign(self, parameters:BaseSignatureParametersTransfers.Sign) -> BaseSignatureResultsTypes.Sign:
|
@@ -18,14 +19,12 @@ class MaleoFoundationSignatureClientService(ClientService):
|
|
18
19
|
)
|
19
20
|
def _impl():
|
20
21
|
try:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
other = "Ensure the given key is of type private key"
|
28
|
-
return BaseSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
22
|
+
private_key = RSAKeyLoader.load_with_pycryptodome(type=BaseEnums.KeyType.PRIVATE, extern_key=parameters.key, passphrase=parameters.password)
|
23
|
+
except TypeError:
|
24
|
+
message = "Invalid key type"
|
25
|
+
description = "A private key must be used for signing a message"
|
26
|
+
other = "Ensure the given key is of type private key"
|
27
|
+
return BaseSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
29
28
|
except Exception as e:
|
30
29
|
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
31
30
|
message = "Invalid key"
|
@@ -39,7 +38,7 @@ class MaleoFoundationSignatureClientService(ClientService):
|
|
39
38
|
return BaseSignatureResultsTransfers.Sign(data=data)
|
40
39
|
return _impl()
|
41
40
|
|
42
|
-
def
|
41
|
+
def decode(self, parameters:BaseSignatureParametersTransfers.Verify) -> BaseSignatureResultsTypes.Verify:
|
43
42
|
@BaseExceptions.service_exception_handler(
|
44
43
|
operation="verify single signature",
|
45
44
|
logger=self._logger,
|
@@ -47,14 +46,12 @@ class MaleoFoundationSignatureClientService(ClientService):
|
|
47
46
|
)
|
48
47
|
def _impl():
|
49
48
|
try:
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
other = "Ensure the given key is of type public key"
|
57
|
-
return BaseSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
49
|
+
public_key = RSAKeyLoader.load_with_pycryptodome(type=BaseEnums.KeyType.PUBLIC, extern_key=parameters.key)
|
50
|
+
except TypeError:
|
51
|
+
message = "Invalid key type"
|
52
|
+
description = "A public key must be used for verifying a signature"
|
53
|
+
other = "Ensure the given key is of type public key"
|
54
|
+
return BaseSignatureResultsTransfers.Fail(message=message, description=description, other=other)
|
58
55
|
except Exception as e:
|
59
56
|
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
60
57
|
message = "Invalid key"
|
@@ -1,11 +1,13 @@
|
|
1
1
|
import jwt
|
2
|
+
from maleo_foundation.enums import BaseEnums
|
3
|
+
from maleo_foundation.expanded_types.token import BaseTokenResultsTypes
|
4
|
+
from maleo_foundation.managers.client.base import ClientService
|
2
5
|
from maleo_foundation.models.schemas.token import BaseTokenSchemas
|
3
6
|
from maleo_foundation.models.transfers.general.token import BaseTokenGeneralTransfers
|
4
7
|
from maleo_foundation.models.transfers.parameters.token import BaseTokenParametersTransfers
|
5
8
|
from maleo_foundation.models.transfers.results.token import BaseTokenResultsTransfers
|
6
|
-
from maleo_foundation.expanded_types.token import BaseTokenResultsTypes
|
7
|
-
from maleo_foundation.managers.client.base import ClientService
|
8
9
|
from maleo_foundation.utils.exceptions import BaseExceptions
|
10
|
+
from maleo_foundation.utils.loaders.key.rsa import RSAKeyLoader
|
9
11
|
|
10
12
|
class MaleoFoundationTokenClientService(ClientService):
|
11
13
|
def encode(self, parameters:BaseTokenParametersTransfers.Encode) -> BaseTokenResultsTypes.Encode:
|
@@ -15,8 +17,21 @@ class MaleoFoundationTokenClientService(ClientService):
|
|
15
17
|
fail_result_class=BaseTokenResultsTransfers.Fail
|
16
18
|
)
|
17
19
|
def _impl():
|
20
|
+
try:
|
21
|
+
private_key = RSAKeyLoader.load_with_pycryptodome(type=BaseEnums.KeyType.PRIVATE, extern_key=parameters.key, passphrase=parameters.password)
|
22
|
+
except TypeError:
|
23
|
+
message = "Invalid key type"
|
24
|
+
description = "A private key must be used for payload encoding"
|
25
|
+
other = "Ensure the given key is of type private key"
|
26
|
+
return BaseTokenResultsTransfers.Fail(message=message, description=description, other=other)
|
27
|
+
except Exception as e:
|
28
|
+
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
29
|
+
message = "Invalid key"
|
30
|
+
description = "Unexpected error occured while trying to import key"
|
31
|
+
other = "Ensure given key is valid"
|
32
|
+
return BaseTokenResultsTransfers.Fail(message=message, description=description, other=other)
|
18
33
|
payload = BaseTokenGeneralTransfers.EncodePayload.model_validate(parameters.payload.model_dump()).model_dump(mode="json")
|
19
|
-
token = jwt.encode(payload=payload, key=
|
34
|
+
token = jwt.encode(payload=payload, key=private_key.export_key(), algorithm="RS256")
|
20
35
|
data = BaseTokenSchemas.Token(token=token)
|
21
36
|
return BaseTokenResultsTransfers.Encode(data=data)
|
22
37
|
return _impl()
|
@@ -28,7 +43,20 @@ class MaleoFoundationTokenClientService(ClientService):
|
|
28
43
|
fail_result_class=BaseTokenResultsTransfers.Fail
|
29
44
|
)
|
30
45
|
def _impl():
|
31
|
-
|
46
|
+
try:
|
47
|
+
public_key = RSAKeyLoader.load_with_pycryptodome(type=BaseEnums.KeyType.PUBLIC, extern_key=parameters.key)
|
48
|
+
except TypeError:
|
49
|
+
message = "Invalid key type"
|
50
|
+
description = "A public key must be used for token decoding"
|
51
|
+
other = "Ensure the given key is of type public key"
|
52
|
+
return BaseTokenResultsTransfers.Fail(message=message, description=description, other=other)
|
53
|
+
except Exception as e:
|
54
|
+
self._logger.error("Unexpected error occured while trying to import key:\n'%s'", str(e), exc_info=True)
|
55
|
+
message = "Invalid key"
|
56
|
+
description = "Unexpected error occured while trying to import key"
|
57
|
+
other = "Ensure given key is valid"
|
58
|
+
return BaseTokenResultsTransfers.Fail(message=message, description=description, other=other)
|
59
|
+
payload = jwt.decode(jwt=parameters.token, key=public_key.export_key(), algorithms=["RS256"])
|
32
60
|
data = BaseTokenGeneralTransfers.DecodePayload.model_validate(payload)
|
33
61
|
return BaseTokenResultsTransfers.Decode(data=data)
|
34
62
|
return _impl()
|
@@ -1,10 +1,21 @@
|
|
1
1
|
import httpx
|
2
2
|
from contextlib import asynccontextmanager
|
3
3
|
from pydantic import BaseModel, Field
|
4
|
-
from typing import AsyncGenerator
|
4
|
+
from typing import AsyncGenerator, Generator
|
5
5
|
from maleo_foundation.types import BaseTypes
|
6
6
|
from maleo_foundation.utils.logging import ClientLogger, SimpleConfig
|
7
7
|
|
8
|
+
class BearerAuth(httpx.Auth):
|
9
|
+
def __init__(self, token:str) -> None:
|
10
|
+
self._auth_header = self._build_auth_header(token)
|
11
|
+
|
12
|
+
def auth_flow(self, request:httpx.Request) -> Generator[httpx.Request, httpx.Response, None]:
|
13
|
+
request.headers["Authorization"] = self._auth_header
|
14
|
+
yield request
|
15
|
+
|
16
|
+
def _build_auth_header(self, token:str) -> str:
|
17
|
+
return f"Bearer {token}"
|
18
|
+
|
8
19
|
class URL(BaseModel):
|
9
20
|
base:str = Field(..., description="Base URL")
|
10
21
|
|
@@ -34,7 +34,19 @@ class Backend(AuthenticationBackend):
|
|
34
34
|
if decode_token_result.data.exp_dt <= datetime.now(tz=timezone.utc):
|
35
35
|
raise AuthenticationError("Expired Bearer token, request new or refresh token")
|
36
36
|
|
37
|
-
|
37
|
+
payload = decode_token_result.data
|
38
|
+
return (
|
39
|
+
Credentials(
|
40
|
+
token=token,
|
41
|
+
payload=payload,
|
42
|
+
scopes=["authenticated", payload.sr]
|
43
|
+
),
|
44
|
+
User(
|
45
|
+
authenticated=True,
|
46
|
+
username=payload.u_u,
|
47
|
+
email=payload.u_e
|
48
|
+
)
|
49
|
+
)
|
38
50
|
|
39
51
|
def add_authentication_middleware(app:FastAPI, keys:BaseGeneralSchemas.RSAKeys, logger:MiddlewareLogger, maleo_foundation:MaleoFoundationClientManager) -> None:
|
40
52
|
"""
|
@@ -1,9 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
from .json import JSONLoader
|
3
|
-
from .key import
|
3
|
+
from .key import BaseKeyLoaders
|
4
4
|
from .yaml import YAMLLoader
|
5
5
|
|
6
6
|
class BaseLoaders:
|
7
7
|
Json = JSONLoader
|
8
|
-
Key =
|
8
|
+
Key = BaseKeyLoaders
|
9
9
|
Yaml = YAMLLoader
|
@@ -0,0 +1,93 @@
|
|
1
|
+
from cryptography.hazmat.primitives import serialization
|
2
|
+
from Crypto.PublicKey import RSA
|
3
|
+
from pathlib import Path
|
4
|
+
from typing import Optional, Union
|
5
|
+
from maleo_foundation.enums import BaseEnums
|
6
|
+
from maleo_foundation.types import BaseTypes
|
7
|
+
|
8
|
+
class RSAKeyLoader:
|
9
|
+
@staticmethod
|
10
|
+
def load_with_cryptography(
|
11
|
+
type:BaseEnums.KeyType,
|
12
|
+
data:Optional[Union[bytes, str]] = None,
|
13
|
+
path:Optional[Union[str, Path]] = None,
|
14
|
+
password:Optional[Union[bytes, str]] = None,
|
15
|
+
format:BaseEnums.KeyFormatType = BaseEnums.KeyFormatType.STRING,
|
16
|
+
) -> Union[bytes, str]:
|
17
|
+
if not isinstance(type, BaseEnums.KeyType):
|
18
|
+
raise TypeError("Invalid key type")
|
19
|
+
|
20
|
+
if data is not None and path is not None:
|
21
|
+
raise ValueError("Only either data or path will be accepted as parameters")
|
22
|
+
|
23
|
+
if data is not None:
|
24
|
+
if isinstance(data, bytes):
|
25
|
+
key_data = data
|
26
|
+
elif isinstance(data, str):
|
27
|
+
key_data = data.encode()
|
28
|
+
else:
|
29
|
+
raise TypeError("Invalid data type")
|
30
|
+
|
31
|
+
if path is not None:
|
32
|
+
file_path = Path(path)
|
33
|
+
|
34
|
+
if not file_path.exists() or not file_path.is_file():
|
35
|
+
raise FileNotFoundError(f"Key file not found: {file_path}")
|
36
|
+
|
37
|
+
key_data = file_path.read_bytes()
|
38
|
+
|
39
|
+
if password is not None and not isinstance(password, (str, bytes)):
|
40
|
+
raise TypeError("Invalid passsword type")
|
41
|
+
|
42
|
+
if not isinstance(format, BaseEnums.KeyFormatType):
|
43
|
+
raise TypeError("Invalid key format type")
|
44
|
+
|
45
|
+
if type == BaseEnums.KeyType.PRIVATE:
|
46
|
+
private_key = serialization.load_pem_private_key(
|
47
|
+
key_data,
|
48
|
+
password=password.encode() if isinstance(password, str) else password,
|
49
|
+
)
|
50
|
+
private_key_bytes = private_key.private_bytes(
|
51
|
+
encoding=serialization.Encoding.PEM,
|
52
|
+
format=serialization.PrivateFormat.PKCS8,
|
53
|
+
encryption_algorithm=serialization.NoEncryption()
|
54
|
+
)
|
55
|
+
if format == BaseEnums.KeyFormatType.BYTES:
|
56
|
+
return private_key_bytes
|
57
|
+
elif format == BaseEnums.KeyFormatType.STRING:
|
58
|
+
return private_key_bytes.decode()
|
59
|
+
|
60
|
+
if type == BaseEnums.KeyType.PUBLIC:
|
61
|
+
public_key = serialization.load_pem_public_key(key_data)
|
62
|
+
public_key_bytes = public_key.public_bytes(
|
63
|
+
encoding=serialization.Encoding.PEM,
|
64
|
+
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
65
|
+
)
|
66
|
+
if format == BaseEnums.KeyFormatType.BYTES:
|
67
|
+
return public_key_bytes
|
68
|
+
elif format == BaseEnums.KeyFormatType.STRING:
|
69
|
+
return public_key_bytes.decode()
|
70
|
+
|
71
|
+
@staticmethod
|
72
|
+
def load_with_pycryptodome(
|
73
|
+
type:BaseEnums.KeyType,
|
74
|
+
extern_key:Union[bytes, str],
|
75
|
+
passphrase:BaseTypes.OptionalString = None,
|
76
|
+
) -> RSA.RsaKey:
|
77
|
+
if not isinstance(type, BaseEnums.KeyType):
|
78
|
+
raise TypeError("Invalid key type")
|
79
|
+
|
80
|
+
if not isinstance(extern_key, (str, bytes)):
|
81
|
+
raise TypeError("Invalid external key type")
|
82
|
+
|
83
|
+
if type == BaseEnums.KeyType.PRIVATE:
|
84
|
+
private_key = RSA.import_key(extern_key=extern_key, passphrase=passphrase)
|
85
|
+
if not private_key.has_private():
|
86
|
+
raise TypeError("Invalid chosen key type, the private key did not has private inside it")
|
87
|
+
return private_key
|
88
|
+
|
89
|
+
if type == BaseEnums.KeyType.PUBLIC:
|
90
|
+
public_key = RSA.import_key(extern_key=extern_key)
|
91
|
+
if public_key.has_private():
|
92
|
+
raise TypeError("Invalid chosen key type, the public key did has private inside it")
|
93
|
+
return public_key
|
@@ -7,8 +7,8 @@ maleo_foundation/types.py,sha256=aKXnIgEhYGSfFqNMGLc4qIKGkINBRpkOo9R9cb2CbwI,241
|
|
7
7
|
maleo_foundation/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
maleo_foundation/client/manager.py,sha256=3YO2uoBLoC9nbe1yNuqPjhgORSDwb5Zu68KLS2zvKXY,1206
|
9
9
|
maleo_foundation/client/services/__init__.py,sha256=SUGBVhs_Zu9rNUxWIxcjGmi54W6RRlwSTqW4h8E0vW0,540
|
10
|
-
maleo_foundation/client/services/signature.py,sha256=
|
11
|
-
maleo_foundation/client/services/token.py,sha256=
|
10
|
+
maleo_foundation/client/services/signature.py,sha256=HGFhdva-4FkEx5s4QSwI2U8y0i2hIyRQCCWLWKQwGp8,4300
|
11
|
+
maleo_foundation/client/services/token.py,sha256=p1cA60ofeFJeL2MVKnAjnggIFniVSp2Hbd7VTYE255E,3880
|
12
12
|
maleo_foundation/expanded_types/__init__.py,sha256=lm_r7rxlLA0sgSTGQBMR9ZbZbVDpD7Te-UYb3oRVi1g,364
|
13
13
|
maleo_foundation/expanded_types/client.py,sha256=To0kRXp3QTmuSu5rWKaCiTsMK9qkYiyYKYbHfw-y1fY,2396
|
14
14
|
maleo_foundation/expanded_types/general.py,sha256=bjIBREYTS73tvS-Key7P7db82a2HHlSJ1XBAvKuYmT0,826
|
@@ -21,13 +21,13 @@ maleo_foundation/managers/db.py,sha256=Pn5EZ-c1Hy6-BihN7KokHJWmBIt3Ty96fZ0zF-srt
|
|
21
21
|
maleo_foundation/managers/middleware.py,sha256=ODIQU1Hpu-Xempjjo_VRbVtxiD5oi74mNuoWuDawRh0,4250
|
22
22
|
maleo_foundation/managers/service.py,sha256=X2NgK5yVRkO5HSVGhN6PgoN-1sGn9w-_PDx1lFVGj2c,16844
|
23
23
|
maleo_foundation/managers/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
|
-
maleo_foundation/managers/client/base.py,sha256=
|
24
|
+
maleo_foundation/managers/client/base.py,sha256=5z9l2GN4QASF0-Lft8o5QQ3SRPXqeNZNT1S1CgaE764,4384
|
25
25
|
maleo_foundation/managers/client/maleo.py,sha256=iCM47TLL-RSQ2FkTmHVPdsb2JCd1LebMx6OJvIr4vCQ,2035
|
26
26
|
maleo_foundation/managers/client/google/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
27
|
maleo_foundation/managers/client/google/base.py,sha256=j3W18Pmcu9jJ5wK12bbWBI6r8cVt5f7QmGU9uIJgKrU,1249
|
28
28
|
maleo_foundation/managers/client/google/secret.py,sha256=Uh01RoOp8QOIvu8X4AGJzOJRlrfAeXHO8ZFvmKo7A-E,3114
|
29
29
|
maleo_foundation/managers/client/google/storage.py,sha256=MPuVpLTl0QJhlBOqpxv5UtD3ANO1WCCE1sRrfHnlCZM,2355
|
30
|
-
maleo_foundation/middlewares/authentication.py,sha256=
|
30
|
+
maleo_foundation/middlewares/authentication.py,sha256=6QerNZjdSrwcE-pHin__Ry517rBBj8mhACrsD_z-YAI,3337
|
31
31
|
maleo_foundation/middlewares/base.py,sha256=8quBiHK4gYARmxnlmcADoNWhv0eGxGaGOFQs2bofbbU,13281
|
32
32
|
maleo_foundation/middlewares/cors.py,sha256=9uvBvY2N6Vxa9RP_YtESxcWo6Doi6uS0lzAG9iLY7Uc,2288
|
33
33
|
maleo_foundation/models/__init__.py,sha256=AaKehO7c1HyKhoTGRmNHDddSeBXkW-_YNrpOGBu8Ms8,246
|
@@ -70,11 +70,12 @@ maleo_foundation/utils/mergers.py,sha256=DniUu3Ot4qkYH_YSw4uD1cn9cfirum4S_Opp8fM
|
|
70
70
|
maleo_foundation/utils/query.py,sha256=ODQ3adOYQNj5E2cRW9ytbjBz56nEDcnfq8mQ6YZbCCM,4375
|
71
71
|
maleo_foundation/utils/formatter/__init__.py,sha256=iKf5YCbEdg1qKnFHyKqqcQbqAqEeRUf8mhI3v3dQoj8,78
|
72
72
|
maleo_foundation/utils/formatter/case.py,sha256=TmvvlfzGdC_omMTB5vAa40TZBxQ3hnr-SYeo0M52Rlg,1352
|
73
|
-
maleo_foundation/utils/loaders/__init__.py,sha256=
|
73
|
+
maleo_foundation/utils/loaders/__init__.py,sha256=RCfPdfgY-F25VDMSA-TWyoczRVUiIDDXpmui8tv5HxM,213
|
74
74
|
maleo_foundation/utils/loaders/json.py,sha256=NsXLq3VZSgzmEf99tV1VtrmiudWdQ8Pzh_hI4Rm0cM8,397
|
75
|
-
maleo_foundation/utils/loaders/key.py,sha256=GZ4h1ONfp6Xx8-E8AWoGP4ajAZrwPhZRtidjn_u82Qg,2562
|
76
75
|
maleo_foundation/utils/loaders/yaml.py,sha256=jr8v3BlgmRCMTzdNgKhIYt1tnubaJXcDSSGkKVR8pbw,362
|
77
|
-
maleo_foundation
|
78
|
-
maleo_foundation
|
79
|
-
maleo_foundation-0.1.
|
80
|
-
maleo_foundation-0.1.
|
76
|
+
maleo_foundation/utils/loaders/key/__init__.py,sha256=G03cA_Oxu02uDsg0WBPfPkIM2uUsxnjwOPgtBKe02kc,110
|
77
|
+
maleo_foundation/utils/loaders/key/rsa.py,sha256=gDhyX6iTFtHiluuhFCozaZ3pOLKU2Y9TlrNMK_GVyGU,3796
|
78
|
+
maleo_foundation-0.1.72.dist-info/METADATA,sha256=2DYADDD2buTe4fJtuusJSZD62BwOcda2IZvrAMal-CM,3390
|
79
|
+
maleo_foundation-0.1.72.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
80
|
+
maleo_foundation-0.1.72.dist-info/top_level.txt,sha256=_iBos3F_bhEOdjOnzeiEYSrCucasc810xXtLBXI8cQc,17
|
81
|
+
maleo_foundation-0.1.72.dist-info/RECORD,,
|
@@ -1,67 +0,0 @@
|
|
1
|
-
from cryptography.hazmat.primitives import serialization
|
2
|
-
from pathlib import Path
|
3
|
-
from typing import Optional, Union
|
4
|
-
from maleo_foundation.enums import BaseEnums
|
5
|
-
|
6
|
-
class KeyLoader:
|
7
|
-
@staticmethod
|
8
|
-
def load_rsa(
|
9
|
-
type:BaseEnums.KeyType,
|
10
|
-
path: Union[str, Path],
|
11
|
-
password:Optional[Union[str, bytes]] = None,
|
12
|
-
format:BaseEnums.KeyFormatType = BaseEnums.KeyFormatType.STRING,
|
13
|
-
) -> Union[bytes, str]:
|
14
|
-
"""
|
15
|
-
Load an RSA private or public key strictly from a file.
|
16
|
-
|
17
|
-
Args:
|
18
|
-
path (str | Path): Path to the PEM file.
|
19
|
-
password (str | bytes | None): Password for encrypted private keys (optional).
|
20
|
-
|
21
|
-
Returns:
|
22
|
-
rsa.RSAPrivateKey | rsa.RSAPublicKey
|
23
|
-
"""
|
24
|
-
if not isinstance(type, BaseEnums.KeyType):
|
25
|
-
raise TypeError("Invalid key type")
|
26
|
-
|
27
|
-
file_path = Path(path)
|
28
|
-
|
29
|
-
if not file_path.is_file():
|
30
|
-
raise FileNotFoundError(f"Key file not found: {file_path}")
|
31
|
-
|
32
|
-
if password is not None and not isinstance(password, (str, bytes)):
|
33
|
-
raise TypeError("Invalid passsword type")
|
34
|
-
|
35
|
-
if not isinstance(format, BaseEnums.KeyFormatType):
|
36
|
-
raise TypeError("Invalid key format type")
|
37
|
-
|
38
|
-
key_data = file_path.read_bytes()
|
39
|
-
|
40
|
-
if type == BaseEnums.KeyType.PRIVATE:
|
41
|
-
private_key = serialization.load_pem_private_key(
|
42
|
-
key_data,
|
43
|
-
password=password.encode() if isinstance(password, str) else password,
|
44
|
-
)
|
45
|
-
private_key_bytes = private_key.private_bytes(
|
46
|
-
encoding=serialization.Encoding.PEM,
|
47
|
-
format=serialization.PrivateFormat.PKCS8,
|
48
|
-
encryption_algorithm=serialization.NoEncryption()
|
49
|
-
)
|
50
|
-
if format == BaseEnums.KeyFormatType.BYTES:
|
51
|
-
return private_key_bytes
|
52
|
-
elif format == BaseEnums.KeyFormatType.STRING:
|
53
|
-
return private_key_bytes.decode()
|
54
|
-
|
55
|
-
elif type == BaseEnums.KeyType.PUBLIC:
|
56
|
-
public_key = serialization.load_pem_public_key(key_data)
|
57
|
-
public_key_bytes = public_key.public_bytes(
|
58
|
-
encoding=serialization.Encoding.PEM,
|
59
|
-
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
60
|
-
)
|
61
|
-
if format == BaseEnums.KeyFormatType.BYTES:
|
62
|
-
return public_key_bytes
|
63
|
-
elif format == BaseEnums.KeyFormatType.STRING:
|
64
|
-
return public_key_bytes.decode()
|
65
|
-
|
66
|
-
else:
|
67
|
-
raise ValueError(f"Unsupported key type: {type}")
|
File without changes
|
File without changes
|