Add bcrypt_test_db, secure_connection
This commit is contained in:
		
							
								
								
									
										111
									
								
								secure_connection/crypto_server.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										111
									
								
								secure_connection/crypto_server.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| #!/usr/bin/env python3 | ||||
| """crypto_server.py | ||||
| ---------------- | ||||
|  | ||||
| This module contains utilities for generating and storing server keys and | ||||
| certificates for the Pylandia Secure Email Initiative. It utilizes the | ||||
| `cryptography` library to create a private key and a self-signed certificate, | ||||
| which are then saved to specified paths. | ||||
|  | ||||
| Functions: | ||||
|     - parse_args() -> Namespace: Parses the command line arguments. | ||||
|     - generate_key_pair(storage_path: Path): Generates a key pair and a | ||||
|       certificate and writes them to the specified storage path. | ||||
| """ | ||||
| from argparse import ArgumentParser, Namespace | ||||
| from datetime import datetime, timedelta | ||||
| from pathlib import Path | ||||
|  | ||||
| from cryptography import x509 | ||||
| from cryptography.hazmat.backends import default_backend | ||||
| from cryptography.hazmat.primitives import hashes, serialization | ||||
| from cryptography.hazmat.primitives.asymmetric import rsa | ||||
| from cryptography.x509.oid import NameOID | ||||
|  | ||||
|  | ||||
| def parse_args() -> Namespace: | ||||
|     """Parses the command line arguments for the script. | ||||
|  | ||||
|     Returns: | ||||
|         Namespace: A namespace object that holds the command line arguments as | ||||
|                    attributes. | ||||
|     """ | ||||
|     parser = ArgumentParser(description="Pylandia Server Key Generator") | ||||
|  | ||||
|     parser.add_argument( | ||||
|         "-p", | ||||
|         "--path", | ||||
|         default="server_keys", | ||||
|         help="Path to save private and public keys", | ||||
|     ) | ||||
|  | ||||
|     return parser.parse_args() | ||||
|  | ||||
|  | ||||
| def generate_key_pair(storage_path: Path): | ||||
|     """Generates a private key and a self-signed certificate and saves them to | ||||
|     the specified storage path. | ||||
|  | ||||
|     Args: | ||||
|         storage_path (Path): The directory where the private key and certificate | ||||
|                              files should be saved. | ||||
|  | ||||
|     Returns: | ||||
|         None | ||||
|     """ | ||||
|     private_key = rsa.generate_private_key( | ||||
|         public_exponent=65537, key_size=4096, backend=default_backend() | ||||
|     ) | ||||
|  | ||||
|     subject = issuer = x509.Name( | ||||
|         [ | ||||
|             x509.NameAttribute(NameOID.COUNTRY_NAME, "PY"), | ||||
|             x509.NameAttribute( | ||||
|                 NameOID.STATE_OR_PROVINCE_NAME, "Central Province" | ||||
|             ), | ||||
|             x509.NameAttribute(NameOID.LOCALITY_NAME, "Pylandia City"), | ||||
|             x509.NameAttribute( | ||||
|                 NameOID.ORGANIZATION_NAME, "Pylandia Secure Email Initiative" | ||||
|             ), | ||||
|             x509.NameAttribute(NameOID.COMMON_NAME, "securemail.pylandia"), | ||||
|         ] | ||||
|     ) | ||||
|  | ||||
|     cert = ( | ||||
|         x509.CertificateBuilder() | ||||
|         .subject_name(subject) | ||||
|         .issuer_name(issuer) | ||||
|         .public_key(private_key.public_key()) | ||||
|         .serial_number(x509.random_serial_number()) | ||||
|         .not_valid_before(datetime.utcnow()) | ||||
|         .not_valid_after(datetime.utcnow() + timedelta(days=365)) | ||||
|         .add_extension( | ||||
|             x509.SubjectAlternativeName([x509.DNSName("localhost")]), | ||||
|             critical=False, | ||||
|         ) | ||||
|         .sign(private_key, hashes.SHA256(), default_backend()) | ||||
|     ) | ||||
|  | ||||
|     if not storage_path.exists(): | ||||
|         storage_path.mkdir(parents=True) | ||||
|  | ||||
|     publickey_path = storage_path / "cert.pem" | ||||
|     with publickey_path.open("wb") as file: | ||||
|         file.write(cert.public_bytes(serialization.Encoding.PEM)) | ||||
|  | ||||
|     privatekey_path = storage_path / "key.pem" | ||||
|     with privatekey_path.open("wb") as file: | ||||
|         file.write( | ||||
|             private_key.private_bytes( | ||||
|                 encoding=serialization.Encoding.PEM, | ||||
|                 format=serialization.PrivateFormat.TraditionalOpenSSL, | ||||
|                 encryption_algorithm=serialization.NoEncryption(), | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     args = parse_args() | ||||
|     storage = args.path | ||||
|     full_storage_path = Path(storage) | ||||
|     generate_key_pair(full_storage_path) | ||||
							
								
								
									
										39
									
								
								secure_connection/secure_client.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										39
									
								
								secure_connection/secure_client.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| #!/usr/bin/env python3 | ||||
| """ | ||||
| A module to establish a non-verifying SSL connection with a server and to  | ||||
| send/receive messages through a secure socket. | ||||
|  | ||||
| Usage: | ||||
|     Run the script to start a communication session with the server at  | ||||
|     "127.0.0.1" on port 9001. Input messages in the console to send to  | ||||
|     the server and receive replies. Type a message with the content  | ||||
|     "quit" to close the connection. | ||||
|  | ||||
| Functions: | ||||
|     main(server_address: str, server_port: int): Initiates a secure socket | ||||
|     communication session with the specified server. | ||||
| """ | ||||
| from socket import create_connection, socket | ||||
| from ssl import SSLContext, PROTOCOL_TLS_CLIENT, CERT_NONE | ||||
|  | ||||
|  | ||||
| def main(server_address: str, server_port: int): | ||||
|     context = SSLContext(PROTOCOL_TLS_CLIENT) | ||||
|     context.check_hostname = False | ||||
|     context.verify_mode = CERT_NONE | ||||
|     unsecure_socket: socket = create_connection( | ||||
|         (server_address, server_port) | ||||
|     ) | ||||
|     secure_socket = context.wrap_socket(unsecure_socket) #, server_hostname="localhost") | ||||
|  | ||||
|     while True: | ||||
|         message = input() | ||||
|         secure_socket.send(message.encode("utf-8")) | ||||
|         reply = secure_socket.recv(len(message)) | ||||
|         if reply == b"quit": | ||||
|             break | ||||
|         print(reply.decode("utf-8")) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main("127.0.0.1", 9001) | ||||
							
								
								
									
										54
									
								
								secure_connection/secure_server.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										54
									
								
								secure_connection/secure_server.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| #!/usr/bin/env python3 | ||||
| """ | ||||
| This module facilitates creating an asynchronous SSL server that echoes | ||||
| received messages. The server operates using SSL certificates stored in  | ||||
| the "server_keys" directory. | ||||
|  | ||||
| Usage: | ||||
|     Run the script to initiate the server on "localhost" at port 9001.  | ||||
|     It listens for incoming connections and echoes messages unless "quit"  | ||||
|     is received, which terminates the connection. | ||||
|  | ||||
| Functions: | ||||
|     handle_client(reader: StreamReader, writer: StreamWriter) -> None: | ||||
|         Handles the communication with a connected client asynchronously. | ||||
|      | ||||
|     main(address: str, port: int) -> None: | ||||
|         Sets up and starts the SSL server with the necessary certificates. | ||||
| """ | ||||
| import logging | ||||
| from asyncio import StreamReader, StreamWriter, run, start_server | ||||
| from pathlib import Path | ||||
| from ssl import Purpose, create_default_context | ||||
|  | ||||
|  | ||||
| async def handle_client(reader: StreamReader, writer: StreamWriter): | ||||
|     while True: | ||||
|         msg_bytes = await reader.read(10) | ||||
|         if msg_bytes == b"quit": | ||||
|             writer.write(b"quit") | ||||
|             await writer.drain() | ||||
|             break | ||||
|         writer.write(msg_bytes) | ||||
|         await writer.drain() | ||||
|  | ||||
|  | ||||
| async def main(address: str, port: int): | ||||
|     storage_path: Path = Path("server_keys") | ||||
|  | ||||
|     keyfile = storage_path / "key.pem" | ||||
|     certfile = storage_path / "cert.pem" | ||||
|     context = create_default_context(Purpose.CLIENT_AUTH) | ||||
|     context.load_cert_chain(certfile, keyfile) | ||||
|  | ||||
|     server = await start_server(handle_client, address, port, ssl=context) | ||||
|  | ||||
|     service_socket = server.sockets[0].getsockname() | ||||
|     logging.info("Serving on %s", service_socket) | ||||
|  | ||||
|     async with server: | ||||
|         await server.serve_forever() | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     run(main("localhost", 9001)) | ||||
		Reference in New Issue
	
	Block a user