mcp-proxy-adapter 6.0.0__py3-none-any.whl → 6.1.0__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.
Files changed (259) hide show
  1. mcp_proxy_adapter/api/app.py +174 -80
  2. mcp_proxy_adapter/api/handlers.py +16 -5
  3. mcp_proxy_adapter/api/middleware/__init__.py +7 -2
  4. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
  5. mcp_proxy_adapter/api/middleware/factory.py +36 -12
  6. mcp_proxy_adapter/api/middleware/unified_security.py +152 -0
  7. mcp_proxy_adapter/api/middleware/user_info_middleware.py +83 -0
  8. mcp_proxy_adapter/commands/__init__.py +7 -1
  9. mcp_proxy_adapter/commands/base.py +7 -4
  10. mcp_proxy_adapter/commands/builtin_commands.py +8 -2
  11. mcp_proxy_adapter/commands/command_registry.py +8 -0
  12. mcp_proxy_adapter/commands/echo_command.py +81 -0
  13. mcp_proxy_adapter/commands/help_command.py +21 -14
  14. mcp_proxy_adapter/commands/proxy_registration_command.py +326 -185
  15. mcp_proxy_adapter/commands/role_test_command.py +141 -0
  16. mcp_proxy_adapter/commands/security_command.py +488 -0
  17. mcp_proxy_adapter/commands/ssl_setup_command.py +2 -2
  18. mcp_proxy_adapter/commands/token_management_command.py +1 -1
  19. mcp_proxy_adapter/config.py +81 -21
  20. mcp_proxy_adapter/core/app_factory.py +326 -0
  21. mcp_proxy_adapter/core/client_security.py +384 -0
  22. mcp_proxy_adapter/core/logging.py +8 -3
  23. mcp_proxy_adapter/core/mtls_asgi.py +156 -0
  24. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  25. mcp_proxy_adapter/core/protocol_manager.py +9 -0
  26. mcp_proxy_adapter/core/proxy_client.py +602 -0
  27. mcp_proxy_adapter/core/proxy_registration.py +299 -47
  28. mcp_proxy_adapter/core/security_adapter.py +12 -15
  29. mcp_proxy_adapter/core/security_integration.py +277 -0
  30. mcp_proxy_adapter/core/server_adapter.py +345 -0
  31. mcp_proxy_adapter/core/server_engine.py +364 -0
  32. mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
  33. mcp_proxy_adapter/examples/README.md +230 -97
  34. mcp_proxy_adapter/examples/README_EN.md +258 -0
  35. mcp_proxy_adapter/examples/SECURITY_TESTING.md +455 -0
  36. mcp_proxy_adapter/examples/__pycache__/security_configurations.cpython-312.pyc +0 -0
  37. mcp_proxy_adapter/examples/__pycache__/security_test_client.cpython-312.pyc +0 -0
  38. mcp_proxy_adapter/examples/basic_framework/configs/http_auth.json +37 -0
  39. mcp_proxy_adapter/examples/basic_framework/configs/http_simple.json +23 -0
  40. mcp_proxy_adapter/examples/basic_framework/configs/https_auth.json +39 -0
  41. mcp_proxy_adapter/examples/basic_framework/configs/https_simple.json +25 -0
  42. mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_roles.json +39 -0
  43. mcp_proxy_adapter/examples/basic_framework/configs/mtls_with_roles.json +45 -0
  44. mcp_proxy_adapter/examples/basic_framework/main.py +63 -0
  45. mcp_proxy_adapter/examples/basic_framework/roles.json +21 -0
  46. mcp_proxy_adapter/examples/cert_config.json +9 -0
  47. mcp_proxy_adapter/examples/certs/admin.crt +32 -0
  48. mcp_proxy_adapter/examples/certs/admin.key +52 -0
  49. mcp_proxy_adapter/examples/certs/admin_cert.pem +21 -0
  50. mcp_proxy_adapter/examples/certs/admin_key.pem +28 -0
  51. mcp_proxy_adapter/examples/certs/ca_cert.pem +23 -0
  52. mcp_proxy_adapter/examples/certs/ca_cert.srl +1 -0
  53. mcp_proxy_adapter/examples/certs/ca_key.pem +28 -0
  54. mcp_proxy_adapter/examples/certs/cert_config.json +9 -0
  55. mcp_proxy_adapter/examples/certs/client.crt +32 -0
  56. mcp_proxy_adapter/examples/certs/client.key +52 -0
  57. mcp_proxy_adapter/examples/certs/client_admin.crt +32 -0
  58. mcp_proxy_adapter/examples/certs/client_admin.key +52 -0
  59. mcp_proxy_adapter/examples/certs/client_user.crt +32 -0
  60. mcp_proxy_adapter/examples/certs/client_user.key +52 -0
  61. mcp_proxy_adapter/examples/certs/guest_cert.pem +21 -0
  62. mcp_proxy_adapter/examples/certs/guest_key.pem +28 -0
  63. mcp_proxy_adapter/examples/certs/mcp_proxy_adapter_ca_ca.crt +23 -0
  64. mcp_proxy_adapter/examples/certs/proxy_cert.pem +21 -0
  65. mcp_proxy_adapter/examples/certs/proxy_key.pem +28 -0
  66. mcp_proxy_adapter/examples/certs/readonly.crt +32 -0
  67. mcp_proxy_adapter/examples/certs/readonly.key +52 -0
  68. mcp_proxy_adapter/examples/certs/readonly_cert.pem +21 -0
  69. mcp_proxy_adapter/examples/certs/readonly_key.pem +28 -0
  70. mcp_proxy_adapter/examples/certs/server.crt +32 -0
  71. mcp_proxy_adapter/examples/certs/server.key +52 -0
  72. mcp_proxy_adapter/examples/certs/server_cert.pem +32 -0
  73. mcp_proxy_adapter/examples/certs/server_key.pem +52 -0
  74. mcp_proxy_adapter/examples/certs/test_ca_ca.crt +20 -0
  75. mcp_proxy_adapter/examples/certs/user.crt +32 -0
  76. mcp_proxy_adapter/examples/certs/user.key +52 -0
  77. mcp_proxy_adapter/examples/certs/user_cert.pem +21 -0
  78. mcp_proxy_adapter/examples/certs/user_key.pem +28 -0
  79. mcp_proxy_adapter/examples/client_configs/api_key_client.json +13 -0
  80. mcp_proxy_adapter/examples/client_configs/basic_auth_client.json +13 -0
  81. mcp_proxy_adapter/examples/client_configs/certificate_client.json +22 -0
  82. mcp_proxy_adapter/examples/client_configs/jwt_client.json +15 -0
  83. mcp_proxy_adapter/examples/client_configs/no_auth_client.json +9 -0
  84. mcp_proxy_adapter/examples/commands/__init__.py +1 -0
  85. mcp_proxy_adapter/examples/create_certificates_simple.py +307 -0
  86. mcp_proxy_adapter/examples/debug_request_state.py +144 -0
  87. mcp_proxy_adapter/examples/debug_role_chain.py +205 -0
  88. mcp_proxy_adapter/examples/demo_client.py +341 -0
  89. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +99 -0
  90. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +106 -0
  91. mcp_proxy_adapter/examples/full_application/configs/http_auth.json +37 -0
  92. mcp_proxy_adapter/examples/full_application/configs/http_simple.json +23 -0
  93. mcp_proxy_adapter/examples/full_application/configs/https_auth.json +39 -0
  94. mcp_proxy_adapter/examples/full_application/configs/https_simple.json +25 -0
  95. mcp_proxy_adapter/examples/full_application/configs/mtls_no_roles.json +39 -0
  96. mcp_proxy_adapter/examples/full_application/configs/mtls_with_roles.json +45 -0
  97. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +97 -0
  98. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +95 -0
  99. mcp_proxy_adapter/examples/full_application/main.py +138 -0
  100. mcp_proxy_adapter/examples/full_application/roles.json +21 -0
  101. mcp_proxy_adapter/examples/generate_all_certificates.py +429 -0
  102. mcp_proxy_adapter/examples/generate_certificates.py +121 -0
  103. mcp_proxy_adapter/examples/keys/ca_key.pem +28 -0
  104. mcp_proxy_adapter/examples/keys/mcp_proxy_adapter_ca_ca.key +28 -0
  105. mcp_proxy_adapter/examples/keys/test_ca_ca.key +28 -0
  106. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log +220 -0
  107. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.1 +1 -0
  108. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.2 +1 -0
  109. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.3 +1 -0
  110. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.4 +1 -0
  111. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.5 +1 -0
  112. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log +220 -0
  113. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.1 +1 -0
  114. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.2 +1 -0
  115. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.3 +1 -0
  116. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.4 +1 -0
  117. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.5 +1 -0
  118. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log +2 -0
  119. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.1 +1 -0
  120. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.2 +1 -0
  121. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.3 +1 -0
  122. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.4 +1 -0
  123. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.5 +1 -0
  124. mcp_proxy_adapter/examples/proxy_registration_example.py +401 -0
  125. mcp_proxy_adapter/examples/roles.json +38 -0
  126. mcp_proxy_adapter/examples/run_example.py +81 -0
  127. mcp_proxy_adapter/examples/run_security_tests.py +326 -0
  128. mcp_proxy_adapter/examples/run_security_tests_fixed.py +300 -0
  129. mcp_proxy_adapter/examples/security_test_client.py +743 -0
  130. mcp_proxy_adapter/examples/server_configs/config_basic_http.json +204 -0
  131. mcp_proxy_adapter/examples/server_configs/config_http_token.json +238 -0
  132. mcp_proxy_adapter/examples/server_configs/config_https.json +215 -0
  133. mcp_proxy_adapter/examples/server_configs/config_https_token.json +231 -0
  134. mcp_proxy_adapter/examples/server_configs/config_mtls.json +215 -0
  135. mcp_proxy_adapter/examples/server_configs/config_proxy_registration.json +250 -0
  136. mcp_proxy_adapter/examples/server_configs/config_simple.json +46 -0
  137. mcp_proxy_adapter/examples/server_configs/roles.json +38 -0
  138. mcp_proxy_adapter/examples/test_examples.py +344 -0
  139. mcp_proxy_adapter/examples/universal_client.py +628 -0
  140. mcp_proxy_adapter/main.py +21 -10
  141. mcp_proxy_adapter/utils/config_generator.py +639 -0
  142. mcp_proxy_adapter/version.py +2 -1
  143. mcp_proxy_adapter-6.1.0.dist-info/METADATA +205 -0
  144. mcp_proxy_adapter-6.1.0.dist-info/RECORD +193 -0
  145. mcp_proxy_adapter-6.1.0.dist-info/entry_points.txt +2 -0
  146. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/licenses/LICENSE +2 -2
  147. mcp_proxy_adapter/api/middleware/auth.py +0 -146
  148. mcp_proxy_adapter/api/middleware/auth_adapter.py +0 -235
  149. mcp_proxy_adapter/api/middleware/mtls_adapter.py +0 -305
  150. mcp_proxy_adapter/api/middleware/mtls_middleware.py +0 -296
  151. mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
  152. mcp_proxy_adapter/api/middleware/rate_limit_adapter.py +0 -241
  153. mcp_proxy_adapter/api/middleware/roles_adapter.py +0 -365
  154. mcp_proxy_adapter/api/middleware/roles_middleware.py +0 -381
  155. mcp_proxy_adapter/api/middleware/security.py +0 -376
  156. mcp_proxy_adapter/api/middleware/token_auth_middleware.py +0 -261
  157. mcp_proxy_adapter/examples/__init__.py +0 -7
  158. mcp_proxy_adapter/examples/basic_server/README.md +0 -60
  159. mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
  160. mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
  161. mcp_proxy_adapter/examples/basic_server/config.json +0 -70
  162. mcp_proxy_adapter/examples/basic_server/config_all_protocols.json +0 -54
  163. mcp_proxy_adapter/examples/basic_server/config_http.json +0 -70
  164. mcp_proxy_adapter/examples/basic_server/config_http_only.json +0 -52
  165. mcp_proxy_adapter/examples/basic_server/config_https.json +0 -58
  166. mcp_proxy_adapter/examples/basic_server/config_mtls.json +0 -58
  167. mcp_proxy_adapter/examples/basic_server/config_ssl.json +0 -46
  168. mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
  169. mcp_proxy_adapter/examples/basic_server/server.py +0 -114
  170. mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
  171. mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
  172. mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -566
  173. mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
  174. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
  175. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
  176. mcp_proxy_adapter/examples/custom_commands/auto_commands/test_command.py +0 -105
  177. mcp_proxy_adapter/examples/custom_commands/catalog/commands/test_command.py +0 -129
  178. mcp_proxy_adapter/examples/custom_commands/config.json +0 -118
  179. mcp_proxy_adapter/examples/custom_commands/config_all_protocols.json +0 -46
  180. mcp_proxy_adapter/examples/custom_commands/config_https_only.json +0 -46
  181. mcp_proxy_adapter/examples/custom_commands/config_https_transport.json +0 -33
  182. mcp_proxy_adapter/examples/custom_commands/config_mtls_only.json +0 -46
  183. mcp_proxy_adapter/examples/custom_commands/config_mtls_transport.json +0 -33
  184. mcp_proxy_adapter/examples/custom_commands/config_single_transport.json +0 -33
  185. mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
  186. mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
  187. mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
  188. mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
  189. mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
  190. mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
  191. mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
  192. mcp_proxy_adapter/examples/custom_commands/full_help_response.json +0 -1
  193. mcp_proxy_adapter/examples/custom_commands/generated_openapi.json +0 -629
  194. mcp_proxy_adapter/examples/custom_commands/get_openapi.py +0 -103
  195. mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
  196. mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
  197. mcp_proxy_adapter/examples/custom_commands/loadable_commands/test_ignored.py +0 -129
  198. mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
  199. mcp_proxy_adapter/examples/custom_commands/proxy_connection_manager.py +0 -278
  200. mcp_proxy_adapter/examples/custom_commands/server.py +0 -252
  201. mcp_proxy_adapter/examples/custom_commands/simple_openapi_server.py +0 -75
  202. mcp_proxy_adapter/examples/custom_commands/start_server_with_proxy_manager.py +0 -299
  203. mcp_proxy_adapter/examples/custom_commands/start_server_with_registration.py +0 -278
  204. mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
  205. mcp_proxy_adapter/examples/custom_commands/test_openapi.py +0 -27
  206. mcp_proxy_adapter/examples/custom_commands/test_registry.py +0 -23
  207. mcp_proxy_adapter/examples/custom_commands/test_simple.py +0 -19
  208. mcp_proxy_adapter/examples/custom_project_example/README.md +0 -103
  209. mcp_proxy_adapter/examples/custom_project_example/README_EN.md +0 -103
  210. mcp_proxy_adapter/examples/deployment/README.md +0 -49
  211. mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
  212. mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
  213. mcp_proxy_adapter/examples/deployment/config.json +0 -29
  214. mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
  215. mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
  216. mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
  217. mcp_proxy_adapter/examples/deployment/run.sh +0 -43
  218. mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
  219. mcp_proxy_adapter/examples/simple_custom_commands/README.md +0 -149
  220. mcp_proxy_adapter/examples/simple_custom_commands/README_EN.md +0 -149
  221. mcp_proxy_adapter/schemas/base_schema.json +0 -114
  222. mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
  223. mcp_proxy_adapter/schemas/roles_schema.json +0 -162
  224. mcp_proxy_adapter/tests/__init__.py +0 -0
  225. mcp_proxy_adapter/tests/api/__init__.py +0 -3
  226. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
  227. mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
  228. mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
  229. mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
  230. mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
  231. mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
  232. mcp_proxy_adapter/tests/commands/__init__.py +0 -3
  233. mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
  234. mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
  235. mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
  236. mcp_proxy_adapter/tests/conftest.py +0 -131
  237. mcp_proxy_adapter/tests/functional/__init__.py +0 -3
  238. mcp_proxy_adapter/tests/functional/test_api.py +0 -253
  239. mcp_proxy_adapter/tests/integration/__init__.py +0 -3
  240. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
  241. mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
  242. mcp_proxy_adapter/tests/performance/__init__.py +0 -3
  243. mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
  244. mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
  245. mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
  246. mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
  247. mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
  248. mcp_proxy_adapter/tests/test_base_command.py +0 -123
  249. mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
  250. mcp_proxy_adapter/tests/test_command_registry.py +0 -281
  251. mcp_proxy_adapter/tests/test_config.py +0 -127
  252. mcp_proxy_adapter/tests/test_utils.py +0 -65
  253. mcp_proxy_adapter/tests/unit/__init__.py +0 -3
  254. mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
  255. mcp_proxy_adapter/tests/unit/test_config.py +0 -270
  256. mcp_proxy_adapter-6.0.0.dist-info/METADATA +0 -201
  257. mcp_proxy_adapter-6.0.0.dist-info/RECORD +0 -179
  258. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/WHEEL +0 -0
  259. {mcp_proxy_adapter-6.0.0.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,429 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Generate All Certificates for Security Testing
4
+
5
+ This script generates all necessary certificates for comprehensive security testing:
6
+ - Root CA certificate and key
7
+ - Server certificates for HTTPS and mTLS
8
+ - Client certificates for different roles (admin, user, readonly, etc.)
9
+ - Test certificates for negative scenarios
10
+
11
+ Author: Vasiliy Zdanovskiy
12
+ email: vasilyvz@gmail.com
13
+ """
14
+
15
+ import json
16
+ import os
17
+ import subprocess
18
+ import sys
19
+ from pathlib import Path
20
+ from typing import Dict, List, Optional
21
+
22
+
23
+ class CertificateGenerator:
24
+ """Generate all certificates for security testing."""
25
+
26
+ def __init__(self):
27
+ self.project_root = Path(__file__).parent.parent.parent
28
+ self.certs_dir = self.project_root / "mcp_proxy_adapter" / "examples" / "certs"
29
+ self.keys_dir = self.project_root / "mcp_proxy_adapter" / "examples" / "keys"
30
+
31
+ # Create directories if they don't exist
32
+ self.certs_dir.mkdir(parents=True, exist_ok=True)
33
+ self.keys_dir.mkdir(parents=True, exist_ok=True)
34
+
35
+ # Certificate configuration
36
+ self.ca_config = {
37
+ "common_name": "MCP Proxy Adapter Test CA",
38
+ "organization": "Test Organization",
39
+ "country": "US",
40
+ "state": "Test State",
41
+ "city": "Test City",
42
+ "validity_years": 10
43
+ }
44
+
45
+ self.server_config = {
46
+ "common_name": "mcp-proxy-adapter-test.local",
47
+ "organization": "Test Organization",
48
+ "country": "US",
49
+ "state": "Test State",
50
+ "city": "Test City",
51
+ "validity_years": 2,
52
+ "san": ["localhost", "127.0.0.1", "mcp-proxy-adapter-test.local"]
53
+ }
54
+
55
+ # Client certificates configuration
56
+ self.client_certs = {
57
+ "admin": {
58
+ "common_name": "admin-client",
59
+ "organization": "Test Organization",
60
+ "roles": ["admin"],
61
+ "permissions": ["*"]
62
+ },
63
+ "user": {
64
+ "common_name": "user-client",
65
+ "organization": "Test Organization",
66
+ "roles": ["user"],
67
+ "permissions": ["read", "write"]
68
+ },
69
+ "readonly": {
70
+ "common_name": "readonly-client",
71
+ "organization": "Test Organization",
72
+ "roles": ["readonly"],
73
+ "permissions": ["read"]
74
+ },
75
+ "guest": {
76
+ "common_name": "guest-client",
77
+ "organization": "Test Organization",
78
+ "roles": ["guest"],
79
+ "permissions": ["read"]
80
+ },
81
+ "proxy": {
82
+ "common_name": "proxy-client",
83
+ "organization": "Test Organization",
84
+ "roles": ["proxy"],
85
+ "permissions": ["register", "discover"]
86
+ }
87
+ }
88
+
89
+ # Negative test certificates
90
+ self.negative_certs = {
91
+ "expired": {
92
+ "common_name": "expired-client",
93
+ "organization": "Test Organization",
94
+ "validity_days": 1 # Will expire quickly
95
+ },
96
+ "wrong_org": {
97
+ "common_name": "wrong-org-client",
98
+ "organization": "Wrong Organization",
99
+ "roles": ["user"]
100
+ },
101
+ "no_roles": {
102
+ "common_name": "no-roles-client",
103
+ "organization": "Test Organization",
104
+ "roles": []
105
+ },
106
+ "invalid_roles": {
107
+ "common_name": "invalid-roles-client",
108
+ "organization": "Test Organization",
109
+ "roles": ["invalid_role"]
110
+ }
111
+ }
112
+
113
+ def run_command(self, cmd: List[str], description: str) -> bool:
114
+ """Run a command and handle errors."""
115
+ try:
116
+ print(f"šŸ”§ {description}...")
117
+ result = subprocess.run(
118
+ cmd,
119
+ cwd=self.project_root,
120
+ capture_output=True,
121
+ text=True,
122
+ check=True
123
+ )
124
+ print(f"āœ… {description} completed successfully")
125
+ return True
126
+ except subprocess.CalledProcessError as e:
127
+ print(f"āŒ {description} failed:")
128
+ print(f" Command: {' '.join(cmd)}")
129
+ print(f" Error: {e.stderr}")
130
+ return False
131
+ except Exception as e:
132
+ print(f"āŒ {description} failed: {e}")
133
+ return False
134
+
135
+ def create_ca_certificate(self) -> bool:
136
+ """Create Root CA certificate and key."""
137
+ ca_cert_path = self.certs_dir / "ca_cert.pem"
138
+ ca_key_path = self.keys_dir / "ca_key.pem"
139
+
140
+ if ca_cert_path.exists() and ca_key_path.exists():
141
+ print(f"ā„¹ļø CA certificate already exists: {ca_cert_path}")
142
+ return True
143
+
144
+ cmd = [
145
+ sys.executable, "-m", "mcp_security_framework.cli.cert_cli", "create-ca",
146
+ "-cn", self.ca_config["common_name"],
147
+ "-o", self.ca_config["organization"],
148
+ "-c", self.ca_config["country"],
149
+ "-s", self.ca_config["state"],
150
+ "-l", self.ca_config["city"],
151
+ "-y", str(self.ca_config["validity_years"])
152
+ ]
153
+
154
+ success = self.run_command(cmd, "Creating Root CA certificate")
155
+
156
+ if success:
157
+ # Move files to correct locations
158
+ default_ca_cert = Path("./certs") / f"{self.ca_config['common_name'].lower().replace(' ', '_')}_ca.crt"
159
+ default_ca_key = Path("./keys") / f"{self.ca_config['common_name'].lower().replace(' ', '_')}_ca.key"
160
+
161
+ if default_ca_cert.exists():
162
+ self.run_command(["mv", str(default_ca_cert), str(ca_cert_path)], "Moving CA certificate")
163
+ if default_ca_key.exists():
164
+ self.run_command(["mv", str(default_ca_key), str(ca_key_path)], "Moving CA key")
165
+
166
+ return success
167
+
168
+ def create_server_certificate(self) -> bool:
169
+ """Create server certificate for HTTPS and mTLS."""
170
+ server_cert_path = self.certs_dir / "server_cert.pem"
171
+ server_key_path = self.certs_dir / "server_key.pem"
172
+
173
+ if server_cert_path.exists() and server_key_path.exists():
174
+ print(f"ā„¹ļø Server certificate already exists: {server_cert_path}")
175
+ return True
176
+
177
+ # Create server certificate
178
+ cmd = [
179
+ sys.executable, "-m", "mcp_security_framework.cli.cert_cli", "create-server",
180
+ "-cn", self.server_config["common_name"],
181
+ "-o", self.server_config["organization"],
182
+ "-c", self.server_config["country"],
183
+ "-s", self.server_config["state"],
184
+ "-l", self.server_config["city"],
185
+ "-d", str(self.server_config["validity_years"] * 365) # Convert years to days
186
+ ]
187
+
188
+ # Add SAN if supported
189
+ if self.server_config["san"]:
190
+ for san in self.server_config["san"]:
191
+ cmd.extend(["--san", san])
192
+
193
+ success = self.run_command(cmd, "Creating server certificate")
194
+
195
+ if success:
196
+ # Move files to correct locations
197
+ default_server_cert = Path("./certs") / f"{self.server_config['common_name'].lower().replace('.', '_')}_server.crt"
198
+ default_server_key = Path("./keys") / f"{self.server_config['common_name'].lower().replace('.', '_')}_server.key"
199
+
200
+ if default_server_cert.exists():
201
+ self.run_command(["mv", str(default_server_cert), str(server_cert_path)], "Moving server certificate")
202
+ if default_server_key.exists():
203
+ self.run_command(["mv", str(default_server_key), str(server_key_path)], "Moving server key")
204
+
205
+ return success
206
+
207
+ def create_client_certificate(self, name: str, config: Dict) -> bool:
208
+ """Create client certificate with specific configuration."""
209
+ cert_path = self.certs_dir / f"{name}_cert.pem"
210
+ key_path = self.certs_dir / f"{name}_key.pem"
211
+
212
+ if cert_path.exists() and key_path.exists():
213
+ print(f"ā„¹ļø Client certificate {name} already exists: {cert_path}")
214
+ return True
215
+
216
+ cmd = [
217
+ sys.executable, "-m", "mcp_security_framework.cli.cert_cli", "create-client",
218
+ "-cn", config["common_name"],
219
+ "-o", config["organization"],
220
+ "-c", self.ca_config["country"],
221
+ "-s", self.ca_config["state"],
222
+ "-l", self.ca_config["city"],
223
+ "-d", "730" # 2 years in days
224
+ ]
225
+
226
+ # Add roles if specified
227
+ if "roles" in config and config["roles"]:
228
+ for role in config["roles"]:
229
+ cmd.extend(["--roles", role])
230
+
231
+ # Add permissions if specified
232
+ if "permissions" in config and config["permissions"]:
233
+ for permission in config["permissions"]:
234
+ cmd.extend(["--permissions", permission])
235
+
236
+ # Add custom validity for negative tests
237
+ if "validity_days" in config:
238
+ cmd[cmd.index("-d") + 1] = str(config["validity_days"])
239
+
240
+ success = self.run_command(cmd, f"Creating client certificate: {name}")
241
+
242
+ if success:
243
+ # Move files to correct locations
244
+ default_client_cert = Path("./certs") / f"{config['common_name'].lower().replace('-', '_')}_client.crt"
245
+ default_client_key = Path("./keys") / f"{config['common_name'].lower().replace('-', '_')}_client.key"
246
+
247
+ if default_client_cert.exists():
248
+ self.run_command(["mv", str(default_client_cert), str(cert_path)], f"Moving {name} certificate")
249
+ if default_client_key.exists():
250
+ self.run_command(["mv", str(default_client_key), str(key_path)], f"Moving {name} key")
251
+
252
+ return success
253
+
254
+ def create_legacy_certificates(self) -> bool:
255
+ """Create legacy certificate files for compatibility."""
256
+ legacy_files = [
257
+ ("client.crt", "client.key"),
258
+ ("client_admin.crt", "client_admin.key"),
259
+ ("admin.crt", "admin.key"),
260
+ ("user.crt", "user.key"),
261
+ ("readonly.crt", "readonly.key")
262
+ ]
263
+
264
+ success = True
265
+ for cert_file, key_file in legacy_files:
266
+ cert_path = self.certs_dir / cert_file
267
+ key_path = self.certs_dir / key_file
268
+
269
+ if not cert_path.exists() or not key_path.exists():
270
+ # Copy from existing certificates
271
+ if cert_file == "client.crt" and (self.certs_dir / "user_cert.pem").exists():
272
+ self.run_command(["cp", str(self.certs_dir / "user_cert.pem"), str(cert_path)], f"Creating {cert_file}")
273
+ self.run_command(["cp", str(self.certs_dir / "user_key.pem"), str(key_path)], f"Creating {key_file}")
274
+ elif cert_file == "client_admin.crt" and (self.certs_dir / "admin_cert.pem").exists():
275
+ self.run_command(["cp", str(self.certs_dir / "admin_cert.pem"), str(cert_path)], f"Creating {cert_file}")
276
+ self.run_command(["cp", str(self.certs_dir / "admin_key.pem"), str(key_path)], f"Creating {key_file}")
277
+ elif cert_file == "admin.crt" and (self.certs_dir / "admin_cert.pem").exists():
278
+ self.run_command(["cp", str(self.certs_dir / "admin_cert.pem"), str(cert_path)], f"Creating {cert_file}")
279
+ self.run_command(["cp", str(self.certs_dir / "admin_key.pem"), str(key_path)], f"Creating {key_file}")
280
+ elif cert_file == "user.crt" and (self.certs_dir / "user_cert.pem").exists():
281
+ self.run_command(["cp", str(self.certs_dir / "user_cert.pem"), str(cert_path)], f"Creating {cert_file}")
282
+ self.run_command(["cp", str(self.certs_dir / "user_key.pem"), str(key_path)], f"Creating {key_file}")
283
+ elif cert_file == "readonly.crt" and (self.certs_dir / "readonly_cert.pem").exists():
284
+ self.run_command(["cp", str(self.certs_dir / "readonly_cert.pem"), str(cert_path)], f"Creating {cert_file}")
285
+ self.run_command(["cp", str(self.certs_dir / "readonly_key.pem"), str(key_path)], f"Creating {key_file}")
286
+
287
+ return success
288
+
289
+ def create_certificate_config(self) -> bool:
290
+ """Create certificate configuration file."""
291
+ config_path = self.certs_dir / "cert_config.json"
292
+
293
+ config = {
294
+ "ca_cert_path": str(self.certs_dir / "ca_cert.pem"),
295
+ "ca_key_path": str(self.keys_dir / "ca_key.pem"),
296
+ "cert_storage_path": str(self.certs_dir),
297
+ "key_storage_path": str(self.keys_dir),
298
+ "default_validity_days": 365,
299
+ "key_size": 2048,
300
+ "hash_algorithm": "sha256"
301
+ }
302
+
303
+ try:
304
+ with open(config_path, 'w') as f:
305
+ json.dump(config, f, indent=2)
306
+ print(f"āœ… Created certificate config: {config_path}")
307
+ return True
308
+ except Exception as e:
309
+ print(f"āŒ Failed to create certificate config: {e}")
310
+ return False
311
+
312
+ def validate_certificates(self) -> bool:
313
+ """Validate all created certificates."""
314
+ print("\nšŸ” Validating certificates...")
315
+
316
+ cert_files = [
317
+ "ca_cert.pem",
318
+ "server_cert.pem",
319
+ "admin_cert.pem",
320
+ "user_cert.pem",
321
+ "readonly_cert.pem",
322
+ "guest_cert.pem",
323
+ "proxy_cert.pem"
324
+ ]
325
+
326
+ success = True
327
+ for cert_file in cert_files:
328
+ cert_path = self.certs_dir / cert_file
329
+ if cert_path.exists():
330
+ try:
331
+ result = subprocess.run(
332
+ ["openssl", "x509", "-in", str(cert_path), "-text", "-noout"],
333
+ capture_output=True,
334
+ text=True,
335
+ check=True
336
+ )
337
+ print(f"āœ… {cert_file}: Valid")
338
+ except subprocess.CalledProcessError:
339
+ print(f"āŒ {cert_file}: Invalid")
340
+ success = False
341
+ else:
342
+ print(f"āš ļø {cert_file}: Not found")
343
+
344
+ return success
345
+
346
+ def generate_all(self) -> bool:
347
+ """Generate all certificates."""
348
+ print("šŸ” Generating All Certificates for Security Testing")
349
+ print("=" * 60)
350
+
351
+ success = True
352
+
353
+ # 1. Create CA certificate
354
+ if not self.create_ca_certificate():
355
+ success = False
356
+ print("āŒ Cannot continue without CA certificate")
357
+ return False
358
+
359
+ # 2. Create server certificate
360
+ if not self.create_server_certificate():
361
+ success = False
362
+
363
+ # 3. Create client certificates for different roles
364
+ print("\nšŸ‘„ Creating client certificates...")
365
+ for name, config in self.client_certs.items():
366
+ if not self.create_client_certificate(name, config):
367
+ success = False
368
+
369
+ # 4. Create negative test certificates
370
+ print("\n🚫 Creating negative test certificates...")
371
+ for name, config in self.negative_certs.items():
372
+ if not self.create_client_certificate(name, config):
373
+ success = False
374
+
375
+ # 5. Create legacy certificates for compatibility
376
+ print("\nšŸ”„ Creating legacy certificates...")
377
+ if not self.create_legacy_certificates():
378
+ success = False
379
+
380
+ # 6. Create certificate configuration
381
+ if not self.create_certificate_config():
382
+ success = False
383
+
384
+ # 7. Validate certificates
385
+ if not self.validate_certificates():
386
+ success = False
387
+
388
+ # Print summary
389
+ print("\n" + "=" * 60)
390
+ print("šŸ“Š CERTIFICATE GENERATION SUMMARY")
391
+ print("=" * 60)
392
+
393
+ if success:
394
+ print("āœ… All certificates generated successfully!")
395
+ print(f"šŸ“ Certificates directory: {self.certs_dir}")
396
+ print(f"šŸ”‘ Keys directory: {self.keys_dir}")
397
+ print("\nšŸ“‹ Generated certificates:")
398
+
399
+ cert_files = list(self.certs_dir.glob("*.pem")) + list(self.certs_dir.glob("*.crt"))
400
+ for cert_file in sorted(cert_files):
401
+ print(f" - {cert_file.name}")
402
+
403
+ key_files = list(self.keys_dir.glob("*.pem")) + list(self.keys_dir.glob("*.key"))
404
+ for key_file in sorted(key_files):
405
+ print(f" - {key_file.name}")
406
+ else:
407
+ print("āŒ Some certificates failed to generate")
408
+ print("Check the error messages above")
409
+
410
+ return success
411
+
412
+
413
+ def main():
414
+ """Main function."""
415
+ generator = CertificateGenerator()
416
+
417
+ try:
418
+ success = generator.generate_all()
419
+ sys.exit(0 if success else 1)
420
+ except KeyboardInterrupt:
421
+ print("\nāš ļø Certificate generation interrupted by user")
422
+ sys.exit(1)
423
+ except Exception as e:
424
+ print(f"\nāŒ Certificate generation failed: {e}")
425
+ sys.exit(1)
426
+
427
+
428
+ if __name__ == "__main__":
429
+ main()
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Certificate Generation Script
4
+
5
+ This script generates all necessary certificates for the examples using
6
+ mcp_security_framework certificate management tools.
7
+
8
+ Author: Vasiliy Zdanovskiy
9
+ email: vasilyvz@gmail.com
10
+ """
11
+
12
+ import os
13
+ import subprocess
14
+ import sys
15
+ from pathlib import Path
16
+
17
+ def run_command(cmd, description):
18
+ """Run a command and handle errors."""
19
+ print(f"šŸ”§ {description}...")
20
+ try:
21
+ result = subprocess.run(cmd, shell=True, check=True, capture_output=True, text=True)
22
+ print(f"āœ… {description} completed successfully")
23
+ return True
24
+ except subprocess.CalledProcessError as e:
25
+ print(f"āŒ {description} failed: {e}")
26
+ print(f"Error output: {e.stderr}")
27
+ return False
28
+
29
+ def main():
30
+ """Generate all certificates for examples."""
31
+ print("šŸ” Certificate Generation Script")
32
+ print("=" * 50)
33
+
34
+ # Create directories
35
+ cert_dir = Path("certs")
36
+ cert_dir.mkdir(exist_ok=True)
37
+
38
+ # Check if mcp_security_framework is available
39
+ try:
40
+ import mcp_security_framework
41
+ print(f"āœ… mcp_security_framework version {mcp_security_framework.__version__} found")
42
+ except ImportError:
43
+ print("āŒ mcp_security_framework not found")
44
+ return False
45
+
46
+ # Generate CA certificate
47
+ if not run_command(
48
+ "python -m mcp_security_framework.cli.cert_cli create-ca "
49
+ "--common-name 'MCP Proxy Adapter CA' "
50
+ "--organization 'MCP Proxy Adapter' "
51
+ "--country 'US' "
52
+ "--state 'State' "
53
+ "--locality 'City' "
54
+ "--validity-years 10 "
55
+ "--key-size 2048",
56
+ "Creating root CA certificate"
57
+ ):
58
+ return False
59
+
60
+ # Generate server certificate
61
+ if not run_command(
62
+ "python -m mcp_security_framework.cli.cert_cli -c cert_config.json create-server "
63
+ "--common-name 'localhost' "
64
+ "--organization 'MCP Proxy Adapter' "
65
+ "--country 'US' "
66
+ "--validity-days 365 "
67
+ "--key-size 2048",
68
+ "Creating server certificate"
69
+ ):
70
+ return False
71
+
72
+ # Generate admin client certificate
73
+ if not run_command(
74
+ "python -m mcp_security_framework.cli.cert_cli -c cert_config.json create-client "
75
+ "--common-name 'admin' "
76
+ "--organization 'MCP Proxy Adapter' "
77
+ "--country 'US' "
78
+ "--validity-days 365 "
79
+ "--key-size 2048 "
80
+ "--roles 'admin' "
81
+ "--permissions 'read,write,delete'",
82
+ "Creating admin client certificate"
83
+ ):
84
+ return False
85
+
86
+ # Generate user client certificate
87
+ if not run_command(
88
+ "python -m mcp_security_framework.cli.cert_cli -c cert_config.json create-client "
89
+ "--common-name 'user' "
90
+ "--organization 'MCP Proxy Adapter' "
91
+ "--country 'US' "
92
+ "--validity-days 365 "
93
+ "--key-size 2048 "
94
+ "--roles 'user' "
95
+ "--permissions 'read,write'",
96
+ "Creating user client certificate"
97
+ ):
98
+ return False
99
+
100
+ # Generate readonly client certificate
101
+ if not run_command(
102
+ "python -m mcp_security_framework.cli.cert_cli -c cert_config.json create-client "
103
+ "--common-name 'readonly' "
104
+ "--organization 'MCP Proxy Adapter' "
105
+ "--country 'US' "
106
+ "--validity-days 365 "
107
+ "--key-size 2048 "
108
+ "--roles 'readonly' "
109
+ "--permissions 'read'",
110
+ "Creating readonly client certificate"
111
+ ):
112
+ return False
113
+
114
+ print("\nšŸŽ‰ All certificates generated successfully!")
115
+ print("šŸ“ Certificates are stored in the 'certs' directory")
116
+
117
+ return True
118
+
119
+ if __name__ == "__main__":
120
+ success = main()
121
+ sys.exit(0 if success else 1)
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDLlJMRJelqXw2E
3
+ AHQf8KnxSbiqY8Ee2q5G7xjgyamBae4HdOcCoLu4GA7mvSmBZDvj6NuVjdYKhKYH
4
+ TzfT1aXgwx9DZykDB9/ApbPYFO3rndu0c5xxST8iJqtLk5YJ+yM04rCv3miQhdSN
5
+ ZjNlInihC5uoOXrVyUgrgxKjOxhkudW1CIaIgaIlbJcftffUzEtcfYgSMc0J3EZX
6
+ E3fvX+9xqWMWfpcoftWMHZpcbV+1dke68s+i5F+98TEG2JxbmlkXgNq0xRdWpcnV
7
+ osU4sYxfKiKCWN5RUlumx9Xh1Mlw4m/C38ZgM3/DWS+0dAl5r4Q0lObBF0ej54U4
8
+ BVgMMOPJAgMBAAECggEAARkcj/ed4jKADqm39qIkMIZ+xgCCvqlcTkqk3jWIQgfx
9
+ vj2Nr3BxgsUyc2Eq06VYQ1rysERTFrxvbtOpD+3zlppG1WS9jmQg+1eJeE1omSBB
10
+ WqBTBDNqcUM3IlG5+fTOVE8yt8gh1UG7i0W1WkLM1sWKweYJeRS8XGu5EoNTltt9
11
+ SDWsx5fCjHMviYhEiHOkkP62ZjdsrH7qYvoR6AeWAUWODy253cWs/Fzj6OeGk7VO
12
+ qLw7i7geWpzmosevfd+fxVJW0UOKKMGngI8xPeJnpQJDL1Vrb+fUeJ0Hu9LXWR9d
13
+ 6LKoP9gaKvXLA4NmkkX+B0+fBVWTR3rAuYRgxLJeAQKBgQD5N1Dw3ocayMM3RqOq
14
+ l6OkGxd+kssnSJN3yZiOBXHy7923mhAMP2KKTP9z3J/CzjWxfRbLEwKWn3Ft2IzM
15
+ WCbQKFTKRWGJeOg0I2k6DI68x7Wqw5kkc3NogxziWOO67UPgHNWsXFR9H9XzAB5+
16
+ RY7THOrHPIjQIeT2xEHeh/UOgQKBgQDRHz3t0iRt3Qj58RxknbXbTA82FijPF2Xc
17
+ ByzJQNZs2+nYlB+S4MB/XCzMfJdP+FrA8BZ5MOT90TBIqYmIo2mnY6/D9XeGaOti
18
+ H8xV45x0C2RlNXCX9Nn4P+j64fZdHVp2+rirNqvyTKN7fKI/Cbd3TMipJUGe77N4
19
+ 5KmPMCFBSQKBgQDPEDrcJsgyZORuJO8Pana4fxoCPI020oJUYNe0CKooo0ugpQz4
20
+ YCHLrzYAWisTfKn4EmrBx8W6yDdCgU5a6lM1WI06knL7+c1UpKdlZ9Gg4H38qA+x
21
+ zYryJx30os50HXbr2olecEhyveTRxiOP3tNQbRJU/+Lcq4zFy0K/Vk8yAQKBgF7J
22
+ 9H46BH0v9YOlgKMywV23qiVwAetsxaToM6q9kvQg8mxTJ8Shz19rXnsJ9mQvRKOz
23
+ r9wbB5DtIx+siUTAHYHcM611NEpegGMn2q0L0Lzg9Q7THEgkmjBmd6pQhiVKytin
24
+ aNFipKndhzTQF5LPSrPuv/27f3UVXZpsu1bGECzRAoGBAIBAJPYmlt8Mfhhvi9Yg
25
+ OXhlqPT7PjRBu+YaoineS5BNZ9V/23ib7iAOClCxdX+7doHI0VKzMyGJR2xa7Rzl
26
+ /oRInNWGU2UV+mCb6FoYohfHX0OFkelKJOZsyxWUrQ93IipwBTomoQnnrEExSzLh
27
+ r0FGAumOHw6zwjmbFSXRbPvs
28
+ -----END PRIVATE KEY-----
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDWjQzvziU+/Y+S
3
+ wXDHXvcG5/ZV3C/R/9JhKZCAJ2g28Dg97Xjf9L8hh+Wzpkj3wDJL2Ho76nMegO5V
4
+ +m/HFVabSA/dn4bxOGqL5v7AXkQrdWRATYMRmGG6lS1NZC6pHRuD/Oun76Jv9aiN
5
+ QyYkLR3iFY8+pQTFhJX2MOO99gmPtAPmy3l3Zu1l2S87TB5Lv8MGuhSuPoNTWzND
6
+ hKP06oX6BCpqmqgkgo0Moy7SaVWAxviyZFjv/SbxUVU1kXqXJpUFoyCHX4ocQqNT
7
+ iGl+M2q0VZm9slhNuisoR7RfAx8eEBcPebOIlqzHBvq3hGgYeWWjnW34OrNwmhx1
8
+ kAPu3CRhAgMBAAECggEACi6y4NAGzSuEMdyDuWKUv2Yo4cBLy1/5yxS0P/DJgw9O
9
+ 4VmGNWgh3g8wuUr4sZFp5wGaI4J9U4Lzohmlo8GBKmjMH/eJ6aQvd6j53tqvyjmN
10
+ uCOK8eh/0uFw6fhe4osixYEuafpMhPBtacQ4aNp0ovM6U33KG9musvrKWYygvYog
11
+ /FUsR/3iUx0FK2Bpa9O7BDNpau7QdBwXyoQAv/BY+lGysdtfwuJOiQdIxg2if15v
12
+ QUgryNV+x6v2mmVV/wiJ/H+3D1Els+BQG5DA3s0IjblEKYKryA6xM5WdSLUCADt4
13
+ gE5V4yJ652iHPGd9X0OZ3wKEz55HJecIW6O8UORQsQKBgQD3uYdVLLMReZxV2tfk
14
+ hoIJ2HEtiJjCmvjnL5fSbLGVTnkCi/S94X02UsKeHnrkzR/QCRzSBKdOkPZXinMZ
15
+ cDYv4z7rNolBMc2Itqq27g5Yxu0NpJ1303QOc3m97O37X8y6r+TYj8frRJrx7iG1
16
+ 9N11j99ZoP9vH2LHcdDubcDL5QKBgQDdt9RYwyFo/vmi8I1KdYBScNXXujf6spPa
17
+ jgeZ3tP8Dkhuf2oABjflK7G4ySIAPl9BDBgc9paY4IcHkgw2YJd5pyYMaCrk4mPg
18
+ NnYCthGIxSzpeqfaFIEavE8/zxeT9jhTh7ScFCFqaUFtzzlzjTzc54MNm5fhc9oq
19
+ 2I4rl9OGzQKBgQCbjSQtl6PZlUNVpdVq6gs9o2tt7BgAGs+wW3I574aS+nOB5eAI
20
+ W08EjXMnVnxUr3kKaK5wMfvcmaoVzhn4Hz3nVApuKBCHn34wGoOX2mOn20F/D57R
21
+ XzXA3UHUwLGu5rjngQtx8NbYJHwm7iC84MUuzOiynyXF4S9ljVJkZQZrAQKBgGOg
22
+ /DlajYPJt1FBeKvxutTQwTasBgWQAyJdWgsJdwY3QNLuTCpwoONIzBZ1wuKLJHBt
23
+ R9ST9b4CfoqnVPeGVeqjclR25ndtR2Xz8vlq6NwlhfXwWMaFGjJyVcYdf8HMDSlz
24
+ vHO6E/3mCDGYwX8sAyJcoaYWuZvkXC+Omev60GEtAoGAeryzTJzl8DHbDKk/3Zvv
25
+ Zo6CbiPh2iBdb6PoPL4cSg/NBDNuHrnWPr/N0RZ5D/cNfA8cv20I1tWBPr+X6r3F
26
+ 2QQKSVt89JqfWJ1Xpj2Nxpnfa3QGFiQFCG5/366rZgASaQsuZNTAVgpbMEpwCjzI
27
+ t0rl84AcRvCvzc67//51jZg=
28
+ -----END PRIVATE KEY-----
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDLj3pcpg4owGNK
3
+ +8KT5FbXuGKYH0577+h9RE0KGC9JrJxCn8O1g62lRcpDCQ8IGwPn97wVGfbAG8ei
4
+ iQUfEPNfkaILv+f2j69tZIbhwuuUjfip8Xy4qcMCYTOnoB8ruwpwiKC8VCmWOOG+
5
+ ma59isHAc0WuNhM+UXmkvEh1CnW3IlmRSilkLAdAI0Z+LkJH6Olb8loFsCcIb3kS
6
+ +FXrviS10eUXxntwNmyHV29svqByS+l5vxloatsMpRZWKZVRr9avYEZhtV37Ae/k
7
+ JD5dqGGa4+5iJJiN9FBmxr7FRJ1/w35fFzR9TP2UyBNhMrEGTii2abITzrSS+nid
8
+ jSBj01kxAgMBAAECggEAUGEvAZ+mjqvtaWIBgvGS4yrRb91I2gKxTKmoPBixr4dj
9
+ yqEYoDfHXTAyPoc4sswsHjCCSdjPSSuPCJzPc2V3nKC+mqIkQAWb0Xf1FPepm6b1
10
+ 7nFHfQm30dw9D+9X76YzaJ1izwrywvliFqfLsZIVkN9TwAdlUOHORWD9wY2oTvAi
11
+ JS7PvTCWuqv4JkAIPZz2UIMBSv7ZajFr4Ysa2Sp9MM2kbIA7uE66HoIF7ic7eD6P
12
+ a6vaFQ23oDs/ZkL73L4goD0283E0HZ/RIBXgFTVvS4bOfbU+ShgRuznX9MmTJIXP
13
+ kgIbgOa3gJhvkKvmLsame9QP7nXzLQiystFqa7B6KwKBgQD1u5ztEkt2CQ1EFjMG
14
+ 9A6kCMPsJHn/HFVbQcs2ZEPiZ7ioTamWZDziP0ykzrymNqkBqOcqEpAj6OUKbFpA
15
+ 8Q1sxVkZZrJmlOMT73Hzv0fyS2sRVH7ee4uFjVd67lVoWjKFOu/CAooz82IkI6r0
16
+ qTGaPbCsz0w4U5ka+ZQWw1RQpwKBgQDUEMi7di8YAZYEwiYNDzee+E6JcJ1z/URU
17
+ 29DO+5YIhVHLft6vLWqe5law/oQlKULN6k3FO/zd977DoS0c9ALgKgDuhf46NXSk
18
+ ukboc2Yplt1LtFOlE7JeYuiHacRHwh+j5ToVlcUVZywXmadDpnNLmWqmivqw9th/
19
+ V/0AiOiqZwKBgQC5ORR9IfgdXY9RTgZibF4IyM6dVZVbdQjlw38gXY1Jv/LRcdCt
20
+ mprF0v67j1VlV/gmVyD/doSNfMQAClIxd0EuRsb1PZKlff54DVlwaDMb8DshEfab
21
+ TraJEVPqRnG8OZixEg6cx3tS01abdQMsbcgEwhFFAPAr2N+kFJHKYqtQKwKBgQCs
22
+ U5dK/pb2YxONeleBdUQ1ooHvndvVTZIhgx8Dk94vvmbhfo9muvlRdswruCeaKxVm
23
+ T2gzRrQNjC0wu+D1DjToBDoNmkUk+Bt5YQYODviOA1KBGmB+XKstmCJtJ72gslcT
24
+ 0EqLD9G/ur9RzkLl7nTykhDglT9yXqU/lji6HoczMQKBgAYhRQeD9pjWPw1+I3Em
25
+ ZwKrAWmOsQKjV4oURU2U/QHKuyzH/H5XkKXpJgpCnYU6XRmIGWvoH/SyLvFv4fhC
26
+ SN8NEoT5JuuMrrJP2m0lWen52ATuuBt/PD+9CSkm9lD9zTG0V9V/he0wYXYv5yYA
27
+ 52PiP265yj3oroWvGzUwJxxR
28
+ -----END PRIVATE KEY-----