From 8ebb40c0f6e8ef3369df8cc61e57e309f392d7f8 Mon Sep 17 00:00:00 2001 From: Faraphel Date: Fri, 5 Jul 2024 00:23:26 +0200 Subject: [PATCH] wrote example for our algorithm and tried to add a cli --- assets/admin/certificate.pem | 20 ++++ assets/admin/private.key | 27 +++++ assets/machine/Beauvais/certificate.pem | 20 ++++ assets/machine/Beauvais/private.key | 27 +++++ mains/__main__.py | 31 ++++++ mains/client.py | 21 ---- mains/role/__init__.py | 3 + mains/role/admin/__init__.py | 2 + mains/role/admin/action/__init__.py | 2 + mains/role/admin/action/create/__init__.py | 2 + mains/role/admin/action/create/argparse.py | 11 ++ .../action/create/create_role/__init__.py | 2 + .../create/create_role/client/__init__.py | 2 + .../create/create_role/client/argparse.py | 8 ++ .../action/create/create_role/client/run.py | 38 +++++++ .../create/create_role/machine/__init__.py | 2 + .../create/create_role/machine/argparse.py | 7 ++ .../action/create/create_role/machine/run.py | 67 ++++++++++++ mains/role/admin/action/create/run.py | 15 +++ mains/role/admin/action/init/__init__.py | 2 + mains/role/admin/action/init/argparse.py | 5 + mains/role/admin/action/init/run.py | 53 +++++++++ mains/role/admin/argparse.py | 11 ++ mains/role/admin/run.py | 15 +++ mains/role/client/__init__.py | 2 + mains/role/client/action/__init__.py | 2 + mains/role/client/action/argparse.py | 9 ++ mains/role/client/action/vote.py | 23 ++++ mains/role/client/argparse.py | 15 +++ mains/role/client/run.py | 13 +++ mains/role/machine/__init__.py | 2 + mains/role/machine/argparse.py | 11 ++ mains/role/machine/run.py | 23 ++++ mains/server.py | 24 ----- requirements.txt | 2 +- source/Card.py | 4 +- source/Machine.py | 9 +- source/__main__.py | 3 - source/models/Proof.py | 2 +- source/wtf/Electeur.py | 16 --- source/wtf/ExempleAutiliser.py | 48 --------- source/wtf/Machine2.py | 23 ---- source/wtf/__init__.py | 0 tests/exemple1.ipynb | 37 ------- tests/exemple1.py | 101 +++++++++++------- tests/exemple2.py | 2 + 46 files changed, 543 insertions(+), 221 deletions(-) create mode 100644 assets/admin/certificate.pem create mode 100644 assets/admin/private.key create mode 100644 assets/machine/Beauvais/certificate.pem create mode 100644 assets/machine/Beauvais/private.key create mode 100644 mains/__main__.py delete mode 100644 mains/client.py create mode 100644 mains/role/__init__.py create mode 100644 mains/role/admin/__init__.py create mode 100644 mains/role/admin/action/__init__.py create mode 100644 mains/role/admin/action/create/__init__.py create mode 100644 mains/role/admin/action/create/argparse.py create mode 100644 mains/role/admin/action/create/create_role/__init__.py create mode 100644 mains/role/admin/action/create/create_role/client/__init__.py create mode 100644 mains/role/admin/action/create/create_role/client/argparse.py create mode 100644 mains/role/admin/action/create/create_role/client/run.py create mode 100644 mains/role/admin/action/create/create_role/machine/__init__.py create mode 100644 mains/role/admin/action/create/create_role/machine/argparse.py create mode 100644 mains/role/admin/action/create/create_role/machine/run.py create mode 100644 mains/role/admin/action/create/run.py create mode 100644 mains/role/admin/action/init/__init__.py create mode 100644 mains/role/admin/action/init/argparse.py create mode 100644 mains/role/admin/action/init/run.py create mode 100644 mains/role/admin/argparse.py create mode 100644 mains/role/admin/run.py create mode 100644 mains/role/client/__init__.py create mode 100644 mains/role/client/action/__init__.py create mode 100644 mains/role/client/action/argparse.py create mode 100644 mains/role/client/action/vote.py create mode 100644 mains/role/client/argparse.py create mode 100644 mains/role/client/run.py create mode 100644 mains/role/machine/__init__.py create mode 100644 mains/role/machine/argparse.py create mode 100644 mains/role/machine/run.py delete mode 100644 mains/server.py delete mode 100644 source/wtf/Electeur.py delete mode 100644 source/wtf/ExempleAutiliser.py delete mode 100644 source/wtf/Machine2.py delete mode 100644 source/wtf/__init__.py delete mode 100644 tests/exemple1.ipynb create mode 100644 tests/exemple2.py diff --git a/assets/admin/certificate.pem b/assets/admin/certificate.pem new file mode 100644 index 0000000..3fdf400 --- /dev/null +++ b/assets/admin/certificate.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIUFiOqi4pgJB9drME4SMSjaF+PoyMwDQYJKoZIhvcNAQEL +BQAwXzELMAkGA1UEBhMCRlIxETAPBgNVBAgMCFByb3ZpbmNlMREwDwYDVQQHDAhM +b2NhbGl0eTEVMBMGA1UECgwMT3JnYW5pemF0aW9uMRMwEQYDVQQDDApkb21haW4u +Y29tMB4XDTI0MDcwNDAwMDI1MVoXDTI1MDcwNTAwMDI1MVowXzELMAkGA1UEBhMC +RlIxETAPBgNVBAgMCFByb3ZpbmNlMREwDwYDVQQHDAhMb2NhbGl0eTEVMBMGA1UE +CgwMT3JnYW5pemF0aW9uMRMwEQYDVQQDDApkb21haW4uY29tMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEApvut4HKl4ZyECZFgL8DGnsr8UJmT7MYwReWJ +Q6nuAucUD8lkWWikYwoSiz57ptpYXLMRLWzOot0h3GBWHB6zcMgFOfTXjrd8heN5 +pknbNQYywVUFJsdN3GXJ1IjSDFNSlsBmDh1mvVmVqWNeGv2rpJSxC6hV0iLMRXYK +J9dLM4IIH2zLUdSkpmzxzOejTH1SYAiqyk91eJvikA0SjlwUC8gRe71HSVIuNqyQ +wVCv/00wjIg6A8Q2fOhFlfvp4IoKCtTviKuDnXIK7Tn02dICHcDeNWis7G8NNosU +nRTbG9UH62eJ0g5IW3e/3ZA4peX20rGwPf599VlFLzGxnW35CwIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQCmH/UHxIcVDjNFQDAQuWe6+UEfOq97qgd4D3j/igAmbfvx +6puPKuCFZKWCeNMb3B9+rFRDHq4NJgbPL22iGUPdZwBjdjt8HZhrheQ+/TEy4Zcf +I6NvuTVAjJmijfHTDQ14koWIrvznlKBNTX1cPtUQnyCrhKpzUUXp9kpuwVlRt5JQ +WpYCJw5XycJiW52vXyZsCd2S1xecD0Pwq5u6+25jM/yblx3s2C2ezcNhIzBufG2i +xz8TSykG+NjhzHfvg8M5eln05kTaf9wHvwkyuH9+WHQUZFeauUzOFX/E6SEJ74s9 +vYssU5Rue2tBOZhuSkqRgE2FsVGJ0ccZQWVfZ6X3 +-----END CERTIFICATE----- diff --git a/assets/admin/private.key b/assets/admin/private.key new file mode 100644 index 0000000..7a9d89c --- /dev/null +++ b/assets/admin/private.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEApvut4HKl4ZyECZFgL8DGnsr8UJmT7MYwReWJQ6nuAucUD8lk +WWikYwoSiz57ptpYXLMRLWzOot0h3GBWHB6zcMgFOfTXjrd8heN5pknbNQYywVUF +JsdN3GXJ1IjSDFNSlsBmDh1mvVmVqWNeGv2rpJSxC6hV0iLMRXYKJ9dLM4IIH2zL +UdSkpmzxzOejTH1SYAiqyk91eJvikA0SjlwUC8gRe71HSVIuNqyQwVCv/00wjIg6 +A8Q2fOhFlfvp4IoKCtTviKuDnXIK7Tn02dICHcDeNWis7G8NNosUnRTbG9UH62eJ +0g5IW3e/3ZA4peX20rGwPf599VlFLzGxnW35CwIDAQABAoIBAEuzh9VcRIWunlF0 +HaYogCMXJSIpLd3Gz7WwZPVPAX9BYV/yzlKWVQgtVdDYp9gx3qNP7vaoAFnnZGVz +KzaeWH1FwNDQhjTGTGaqhMj1bLJyN+pb7/TvoAXOA50d1hQOZj+/w8ScYapwBaCA +UvZrkDgRzN3bF+UnL3JCHEKJoScdDCGZGlvM/c7hQZYyZ94MuUT9+njkymGXm/H2 +Xkyf1AWnXMeQRs1vBLwtNxshQzfpoEAuYQ01mNjaHNyyW8/VYXzY+cUUDjuQMoxR +0VT/3N7IJFrdQdw2d5nfae59iX+mJM3dZ5hsSNimN9p4Q+5jG6uDOJP6QC/TKkDm +gYLFf/ECgYEA63q9cJuQ4CYbCRllyR/JhjeczT87D9wCE4/TxPLHIRbYXUTwvVbd +tII4lHR4mnsJUVK+cDhXzPWtgLhFZ3oY7tjv89Nj8SMAZA+gh7XLS8mYuvG8OjgJ +TZoJbSOGR5RJDV5BLxaR2czC+si/IsDn2rEjuAeBzu7cdBd6yq7EUjMCgYEAtYje +kn62UQjqCPcprA5Zumki8zBJfQlHXOPJh58hczla+T+wyFCMA4e3rE2ZYUUeCUZu +fM+qbqAP7CQW2lY7msidtlH+uhutgjCmJ9mHFpFS9bN7iRX7t6oGfnQJ13nvoaF0 +7D8ebxVnn5paCeu4vUBQ2mYKxjhJdnTx/3yH1ckCgYBG0OG5xL77+dm1kdK/enTD +jWP1gaeEbHifY2ifWRezhshIvFvdxQrlpyfW1XQTmR7DOywUWY1mERg9lq0gomJv +KgR3gkITGaCbduujBHP/9b+dsOcXZxS9Jq7hCIbwbdLOV2MpAxOXuXGFs+tvSy4u +4YjJZlCOZ90aeJkv7QETawKBgEmzQqF5Hi2yD8oKBnoa7WTX8F+JGBzSWo2k0Rnl +iiAMhhmxOOVqhh2cyP4EFyQ9el9Ln+m+KbR1+WDmmfyUi+hgUF9H1MHcIMo9VAfT +sZuA7oxgDORv71z2g2JtW92GXLpjIWQUkBeLOiG6+ZkTgVIcPXcdfHxTN8gG3ITc +Gw25AoGAcdR8DNJO/Oo7BlZKV/g5nUSzbdgIrT2gtT6ZUBaQZw3mLjiMHFfihtPn +hXfmXZ+ymaXxm6IRGcz9c28V0a9M+q29P1hWfQQVCk7yEdMHxlE4FBVg7ejIhw07 +8dgM9v8tg6Nf3b0KGWrgnD87ds3uR6D536Bhh3jmhq27U8k45OY= +-----END RSA PRIVATE KEY----- diff --git a/assets/machine/Beauvais/certificate.pem b/assets/machine/Beauvais/certificate.pem new file mode 100644 index 0000000..cbbf9de --- /dev/null +++ b/assets/machine/Beauvais/certificate.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIUaZDZAVUe0kK/3m6RxCg44Rv8ToswDQYJKoZIhvcNAQEL +BQAwXzELMAkGA1UEBhMCRlIxETAPBgNVBAgMCFByb3ZpbmNlMREwDwYDVQQHDAhM +b2NhbGl0eTEVMBMGA1UECgwMT3JnYW5pemF0aW9uMRMwEQYDVQQDDApkb21haW4u +Y29tMB4XDTI0MDcwNDAwMDI1NVoXDTI1MDcwNTAwMDI1NVowXzELMAkGA1UEBhMC +RlIxETAPBgNVBAgMCFByb3ZpbmNlMREwDwYDVQQHDAhMb2NhbGl0eTEVMBMGA1UE +CgwMT3JnYW5pemF0aW9uMRMwEQYDVQQDDApkb21haW4uY29tMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0xfSOKdy/FKvLsNatkdg22vbwgKHjHeS0kXu +k+MVHvbp+r2uwwhbYilhLWBk6OM94ftVJh0441bkCnoPACMd1goqxvUkP4m+4uaX ++lVup5JHAre5YXher3rX5K1Jyd7Rns7V0q01y6J7LnjRSMY2hZIgrQEoVc+HXVqS +idPaOl30W4U12UQv405y+yAHCjqWZEp9ZNO7cg6zMQCGyTs+u9/4wyqXIrXly0Br +R/MV1VyCvBSpT0913WksRXb2xJvPSwsiRGzgKJ0/LtiFC3hfNZWkfi4FVRazYO69 +OPiXw+MbmodI9ie2TNvmk7TuxFPntrm9P0YqsOacymOYXS05uwIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQBaNv/xmhRBmBfJQXnA8N03xg9vYlC0VyHQzhYRQ3kE9wb7 +j4/lzbDgqRb5ok2zIrPPewcwZ4yM5tIyi78I0dYPtlCSLEyEqQJ2kNfYHWnKvC5D +ipDeJrymCz0VGNAAqH9Ib18HoxrLM2+tQtavs6p0Iu9V14H3D/ouJhdfQV04PvgC +8QFFCmrvqw8WSAzhoXaD9pAxCQc4fJIDrMUN45nOjIUjSdi4vGClIryJ2Fmz7LP+ +a/ZqciybqgybLz5pGp9gPFL7FKhw/sgypP7HqvUEyw+mejLNxcDXbmk+01Wjspfj +VAi/u0nCupYv5UfBVyPG6vBZ4qcOcX89qkHv4xl9 +-----END CERTIFICATE----- diff --git a/assets/machine/Beauvais/private.key b/assets/machine/Beauvais/private.key new file mode 100644 index 0000000..3f4bc26 --- /dev/null +++ b/assets/machine/Beauvais/private.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA0xfSOKdy/FKvLsNatkdg22vbwgKHjHeS0kXuk+MVHvbp+r2u +wwhbYilhLWBk6OM94ftVJh0441bkCnoPACMd1goqxvUkP4m+4uaX+lVup5JHAre5 +YXher3rX5K1Jyd7Rns7V0q01y6J7LnjRSMY2hZIgrQEoVc+HXVqSidPaOl30W4U1 +2UQv405y+yAHCjqWZEp9ZNO7cg6zMQCGyTs+u9/4wyqXIrXly0BrR/MV1VyCvBSp +T0913WksRXb2xJvPSwsiRGzgKJ0/LtiFC3hfNZWkfi4FVRazYO69OPiXw+MbmodI +9ie2TNvmk7TuxFPntrm9P0YqsOacymOYXS05uwIDAQABAoIBABjvZ+w8T3dh1wK5 +ndYJUXYp5AAjZ1qe50+CZj++48hQF2yAiovMSWsrgyimidT+vtkaZMEHU6h7I53f +NDVqcIRPmCT/YSRGQ6+u2IYAIH2X6F54UGQkoV6uLqF7HMvFT9KoERb9Uez3iQCA +0gv8KgWWMNju2ZJlXNKYt9WjGlSpfIVbAxdGlFNWGKwWvAypfXMfdJY5P5U+Lk1Q +CqNZ/U1B5uaqbVbd9RfQJYtZny3h2OQGf4nSDXE2Gq63fOIbPdISjhaYCnHWBoBD +HzaO14tbz7hGeHLmNLB8p5SeoY1ZOA10YTdF1jtH+4gloKEwf1vcxUEXf3novn1X +f8NB620CgYEA9y+3wAx91c2sK57HVJEuicp9xmtXNjKVeoPnuk50DGjL4D/V3C1r +eM7hGfbD/98euSMkNs0F7zIkqXiBC45U4wOIaQHgVZbJM5Mhdvh4S7pZstETUA7k +XrN+c71ktms8fg7EjiBRfzi3wULWk5bmjKsc+sTlPACCFUt4zYe6zS0CgYEA2p6m +AtxYLkWA0Ci6xho4xU0iKCmGHeR+R4YuLd60/L7PHAySMCBzrha8jx9PpAppi27M +DaOu9H9VpNnApGBJVuHDTRq672ZPpPQ8Rbj8ZvCQ6TlsoMJuEO4kcTBfccYVCNS+ +wYbRWpteK7GfL6YXC5HdxL9vFV2hpK0IFmuBg4cCgYEAyOddv5fnhqidsO5iMFe3 +rYKI64Y+4ewHFgazhvdQ1u0uF1uK5GN+IDh1OHcaIpMkE3F+c5P7qMfmiF9K8yuB +zukGK+K8hJQDgAmrf1i/3TzevrmzqrQP5PCabFOY0bMi/YnfM20NEAv3PfqnEFnr +lJVW/nKdpkD7eXdX/iS9LRkCgYEAhzv0PXjII3djA2DuiHTYAVSBeI6XJA6f/uaF +0mIdWus9eoBcPeEVLe9qnK4lubenKlVTbGyAYUYTWHJKtGPLei8VfLC4SjbjtYpP +bmHL4HGXcm3PQHKFW3u0lz/xCpQZlujjRxt6ja3mRukNK5B2WPXWVUqGEJVm1FMk +2ZmO+CkCgYA6X1eHTPfY9Wy7uQEyamA6H/nUGFyKM85tGYU0D7xdU9ls0VFTuME4 +0FAq8k1k9BbSAhrpsyYp/eIAHJ3gF88w/NyP/1HO1RTzpLcXiI/fzGb59i4hY6Gg +g7AyGGe62nfVhAD/WaMp+0iidXtd/ZwR09PaECUuU+UJ91BojlbwzA== +-----END RSA PRIVATE KEY----- diff --git a/mains/__main__.py b/mains/__main__.py new file mode 100644 index 0000000..fd1afd0 --- /dev/null +++ b/mains/__main__.py @@ -0,0 +1,31 @@ +import argparse + +from mains import role + +parser = argparse.ArgumentParser() +subparsers = parser.add_subparsers(dest="role") + +role.admin.load_parse(subparsers) +role.client.load_parse(subparsers) +role.machine.load_parse(subparsers) + + +arguments = parser.parse_args() + + +if not arguments: + parser.print_help() + exit(1) + + +match arguments.role: + case "admin": + role.admin.run(parser, arguments) + case "machine": + role.machine.run(parser, arguments) + case "client": + role.client.run(parser, arguments) + + # if the role is unknown, show the usage + case _: + parser.print_usage() diff --git a/mains/client.py b/mains/client.py deleted file mode 100644 index 8074602..0000000 --- a/mains/client.py +++ /dev/null @@ -1,21 +0,0 @@ -import argparse - - -arg_parser = argparse.ArgumentParser() - -arg_parser.add_argument("-H", "--host", dest="hostname", type=str, default="127.0.0.1") -arg_parser.add_argument("-p", "--port", dest="port", type=int, default=57823) - -arguments = arg_parser.parse_args() - - -if arguments: - import ssl - import socket - - context = ssl.create_default_context() - - with socket.create_connection((arguments.hostname, 443)) as sock_client: - with context.wrap_socket(sock_client, server_hostname=arguments.hostname) as ssl_sock_client: - print(ssl_sock_client.version()) - ssl_sock_client.send(b"Hello World!") diff --git a/mains/role/__init__.py b/mains/role/__init__.py new file mode 100644 index 0000000..f9891e8 --- /dev/null +++ b/mains/role/__init__.py @@ -0,0 +1,3 @@ +from . import admin +from . import client +from . import machine diff --git a/mains/role/admin/__init__.py b/mains/role/admin/__init__.py new file mode 100644 index 0000000..05e733e --- /dev/null +++ b/mains/role/admin/__init__.py @@ -0,0 +1,2 @@ +from .argparse import load_parse +from .run import run diff --git a/mains/role/admin/action/__init__.py b/mains/role/admin/action/__init__.py new file mode 100644 index 0000000..3726bb0 --- /dev/null +++ b/mains/role/admin/action/__init__.py @@ -0,0 +1,2 @@ +from . import create +from . import init diff --git a/mains/role/admin/action/create/__init__.py b/mains/role/admin/action/create/__init__.py new file mode 100644 index 0000000..05e733e --- /dev/null +++ b/mains/role/admin/action/create/__init__.py @@ -0,0 +1,2 @@ +from .argparse import load_parse +from .run import run diff --git a/mains/role/admin/action/create/argparse.py b/mains/role/admin/action/create/argparse.py new file mode 100644 index 0000000..ce16f6c --- /dev/null +++ b/mains/role/admin/action/create/argparse.py @@ -0,0 +1,11 @@ +import argparse + +from . import create_role + + +def load_parse(subparsers): + subparser: argparse.ArgumentParser = subparsers.add_parser("create") + + subsubparsers = subparser.add_subparsers(dest="create_role") + create_role.client.load_parse(subsubparsers) + create_role.machine.load_parse(subsubparsers) diff --git a/mains/role/admin/action/create/create_role/__init__.py b/mains/role/admin/action/create/create_role/__init__.py new file mode 100644 index 0000000..9bfc5e8 --- /dev/null +++ b/mains/role/admin/action/create/create_role/__init__.py @@ -0,0 +1,2 @@ +from . import machine +from . import client diff --git a/mains/role/admin/action/create/create_role/client/__init__.py b/mains/role/admin/action/create/create_role/client/__init__.py new file mode 100644 index 0000000..05e733e --- /dev/null +++ b/mains/role/admin/action/create/create_role/client/__init__.py @@ -0,0 +1,2 @@ +from .argparse import load_parse +from .run import run diff --git a/mains/role/admin/action/create/create_role/client/argparse.py b/mains/role/admin/action/create/create_role/client/argparse.py new file mode 100644 index 0000000..168f567 --- /dev/null +++ b/mains/role/admin/action/create/create_role/client/argparse.py @@ -0,0 +1,8 @@ +import argparse + + +def load_parse(subparsers): + subparser: argparse.ArgumentParser = subparsers.add_parser("client") + + subparser.add_argument("-u", "--username", dest="username", type=str, required=True) + subparser.add_argument("-p", "--password", dest="password", type=str, required=True) diff --git a/mains/role/admin/action/create/create_role/client/run.py b/mains/role/admin/action/create/create_role/client/run.py new file mode 100644 index 0000000..2240bbf --- /dev/null +++ b/mains/role/admin/action/create/create_role/client/run.py @@ -0,0 +1,38 @@ +import argparse +from pathlib import Path + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import rsa + + +def run(parser: argparse.ArgumentParser, arguments: argparse.Namespace): + # TODO(Faraphel): should NOT be named "client" + print("creating new client...") + + directory_client = Path(f"./assets/client/{arguments.username}/") + if directory_client.exists(): + raise ValueError("This client already exists !") + + directory_client.mkdir(parents=True) + + # Generate a private key + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=2048, + backend=default_backend(), + ) + + (directory_client / "private.key").write_bytes( + private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.OpenSSH, + encryption_algorithm=serialization.BestAvailableEncryption(arguments.password.encode()), + ) + ) + (directory_client / "public.key").write_bytes( + private_key.public_key().public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.OpenSSH, + ) + ) diff --git a/mains/role/admin/action/create/create_role/machine/__init__.py b/mains/role/admin/action/create/create_role/machine/__init__.py new file mode 100644 index 0000000..05e733e --- /dev/null +++ b/mains/role/admin/action/create/create_role/machine/__init__.py @@ -0,0 +1,2 @@ +from .argparse import load_parse +from .run import run diff --git a/mains/role/admin/action/create/create_role/machine/argparse.py b/mains/role/admin/action/create/create_role/machine/argparse.py new file mode 100644 index 0000000..12dc002 --- /dev/null +++ b/mains/role/admin/action/create/create_role/machine/argparse.py @@ -0,0 +1,7 @@ +import argparse + + +def load_parse(subparsers): + subparser: argparse.ArgumentParser = subparsers.add_parser("machine") + + subparser.add_argument("-n", "--name", dest="name", type=str, required=True) diff --git a/mains/role/admin/action/create/create_role/machine/run.py b/mains/role/admin/action/create/create_role/machine/run.py new file mode 100644 index 0000000..01bc329 --- /dev/null +++ b/mains/role/admin/action/create/create_role/machine/run.py @@ -0,0 +1,67 @@ +import argparse +from datetime import datetime, timedelta +from pathlib import Path + +from cryptography import x509 +from cryptography.hazmat.primitives import serialization, hashes +from cryptography.hazmat.primitives.asymmetric import rsa + + +def run(parser: argparse.ArgumentParser, arguments: argparse.Namespace): + print("creating a new machine...") + + directory_admin = Path("./assets/admin/") + if not directory_admin.exists(): + raise ValueError("Can't find the admin. Have you initialized it ?") + + directory_machine = Path(f"./assets/machine/{arguments.name}/") + if directory_machine.exists(): + raise ValueError("This machine already exists !") + + directory_machine.mkdir(parents=True) + + # Generate a private key + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=2048, + ) + + (directory_machine / "private.key").write_bytes( + private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=serialization.NoEncryption(), + ) + ) + + certificate_admin = x509.load_pem_x509_certificate( + (directory_admin / "certificate.pem").read_bytes() + ) + private_key_admin = serialization.load_pem_private_key( + (directory_admin / "private.key").read_bytes(), + password=None + ) + + # Generate a self-signed root certificate + subject = x509.Name([ + x509.NameAttribute(x509.NameOID.COUNTRY_NAME, "FR"), + x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, "Province"), + x509.NameAttribute(x509.NameOID.LOCALITY_NAME, "Locality"), + x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, "Organization"), + x509.NameAttribute(x509.NameOID.COMMON_NAME, "domain.com"), + ]) + certificate = ( + x509.CertificateBuilder() + .subject_name(subject) + .issuer_name(certificate_admin.subject) + .public_key(private_key.public_key()) + .serial_number(x509.random_serial_number()) + .not_valid_before(datetime.now() - timedelta(days=1)) # TODO(Faraphel): settings + .not_valid_after(datetime.now() + timedelta(days=365)) # TODO(Faraphel): settings + .sign(private_key_admin, hashes.SHA256()) + ) + + # Save the root certificate to a file + (directory_machine / "certificate.pem").write_bytes(certificate.public_bytes(serialization.Encoding.PEM)) + + print("machine created !") diff --git a/mains/role/admin/action/create/run.py b/mains/role/admin/action/create/run.py new file mode 100644 index 0000000..0539d0c --- /dev/null +++ b/mains/role/admin/action/create/run.py @@ -0,0 +1,15 @@ +import argparse + +from . import create_role + + +def run(parser: argparse.ArgumentParser, arguments: argparse.Namespace): + match arguments.create_role: + case "client": + create_role.client.run(parser, arguments) + case "machine": + create_role.machine.run(parser, arguments) + + # if the subcommand is not known, show the help + case _: + parser.print_usage() diff --git a/mains/role/admin/action/init/__init__.py b/mains/role/admin/action/init/__init__.py new file mode 100644 index 0000000..05e733e --- /dev/null +++ b/mains/role/admin/action/init/__init__.py @@ -0,0 +1,2 @@ +from .argparse import load_parse +from .run import run diff --git a/mains/role/admin/action/init/argparse.py b/mains/role/admin/action/init/argparse.py new file mode 100644 index 0000000..1e1498b --- /dev/null +++ b/mains/role/admin/action/init/argparse.py @@ -0,0 +1,5 @@ +import argparse + + +def load_parse(subparsers): + subparser: argparse.ArgumentParser = subparsers.add_parser("init") diff --git a/mains/role/admin/action/init/run.py b/mains/role/admin/action/init/run.py new file mode 100644 index 0000000..deb3ea0 --- /dev/null +++ b/mains/role/admin/action/init/run.py @@ -0,0 +1,53 @@ +import argparse +from datetime import datetime, timedelta +from pathlib import Path + +from cryptography import x509 +from cryptography.hazmat.primitives import serialization, hashes +from cryptography.hazmat.primitives.asymmetric import rsa + + +def run(parser: argparse.ArgumentParser, arguments: argparse.Namespace): + print("initializing the admin...") + + directory = Path(f"./assets/admin/") + if directory.exists(): + raise ValueError("The admin already exists !") + + directory.mkdir(parents=True) + + # Generate a private key + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=4096, + ) + + (directory / "private.key").write_bytes( + private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=serialization.NoEncryption(), + ) + ) + + # Generate a self-signed root certificate + subject = x509.Name([ + x509.NameAttribute(x509.NameOID.COUNTRY_NAME, "FR"), + x509.NameAttribute(x509.NameOID.STATE_OR_PROVINCE_NAME, "Province"), + x509.NameAttribute(x509.NameOID.LOCALITY_NAME, "Locality"), + x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, "Organization"), + x509.NameAttribute(x509.NameOID.COMMON_NAME, "domain.com"), + ]) + certificate = ( + x509.CertificateBuilder() + .subject_name(subject) + .issuer_name(subject) + .public_key(private_key.public_key()) + .serial_number(x509.random_serial_number()) + .not_valid_before(datetime.now() - timedelta(days=1)) # TODO(Faraphel): settings + .not_valid_after(datetime.now() + timedelta(days=365)) # TODO(Faraphel): settings + .sign(private_key, hashes.SHA256()) + ) + + # Save the root certificate to a file + (directory / "certificate.pem").write_bytes(certificate.public_bytes(serialization.Encoding.PEM)) diff --git a/mains/role/admin/argparse.py b/mains/role/admin/argparse.py new file mode 100644 index 0000000..9b2f141 --- /dev/null +++ b/mains/role/admin/argparse.py @@ -0,0 +1,11 @@ +import argparse + +from . import action + + +def load_parse(subparsers): + subparser: argparse.ArgumentParser = subparsers.add_parser("admin") + + subsubparsers = subparser.add_subparsers(dest="action") + action.create.load_parse(subsubparsers) + action.init.load_parse(subsubparsers) diff --git a/mains/role/admin/run.py b/mains/role/admin/run.py new file mode 100644 index 0000000..19ce0fd --- /dev/null +++ b/mains/role/admin/run.py @@ -0,0 +1,15 @@ +import argparse + +from . import action + + +def run(parser: argparse.ArgumentParser, arguments: argparse.Namespace): + match arguments.action: + case "create": + action.create.run(parser, arguments) + case "init": + action.init.run(parser, arguments) + + # if the subcommand is not known, show the help + case _: + parser.print_usage() diff --git a/mains/role/client/__init__.py b/mains/role/client/__init__.py new file mode 100644 index 0000000..05e733e --- /dev/null +++ b/mains/role/client/__init__.py @@ -0,0 +1,2 @@ +from .argparse import load_parse +from .run import run diff --git a/mains/role/client/action/__init__.py b/mains/role/client/action/__init__.py new file mode 100644 index 0000000..363a3a9 --- /dev/null +++ b/mains/role/client/action/__init__.py @@ -0,0 +1,2 @@ +from . import vote +from .argparse import load_parse diff --git a/mains/role/client/action/argparse.py b/mains/role/client/action/argparse.py new file mode 100644 index 0000000..b839c64 --- /dev/null +++ b/mains/role/client/action/argparse.py @@ -0,0 +1,9 @@ +import argparse + + +def load_parse(subparsers): + subparser: argparse.ArgumentParser = subparsers.add_parser("vote") + + subparser.add_argument("-u", "--username", dest="username", type=str, required=True) + subparser.add_argument("-p", "--password", dest="password", type=str, required=True) + subparser.add_argument("-v", "--vote", dest="vote", type=str, required=True) diff --git a/mains/role/client/action/vote.py b/mains/role/client/action/vote.py new file mode 100644 index 0000000..fa8eebe --- /dev/null +++ b/mains/role/client/action/vote.py @@ -0,0 +1,23 @@ +import argparse +import json +import ssl +import socket + + +def run(parser: argparse.ArgumentParser, arguments: argparse.Namespace): + context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT) + context.load_verify_locations(arguments.certificate) + context.check_hostname = False + + with ( + socket.create_connection((arguments.hostname, arguments.port)) as sock_client, + context.wrap_socket(sock_client, server_hostname=arguments.hostname) as ssl_sock_client + ): + data = { + "username": arguments.username, + "password": arguments.password, + "vote": arguments.vote, + } + + ssl_sock_client.send(json.dumps(data).encode()) + print("message sent.") diff --git a/mains/role/client/argparse.py b/mains/role/client/argparse.py new file mode 100644 index 0000000..65e5b7a --- /dev/null +++ b/mains/role/client/argparse.py @@ -0,0 +1,15 @@ +import argparse +from pathlib import Path + +from . import action + + +def load_parse(subparsers): + subparser: argparse.ArgumentParser = subparsers.add_parser("client") + + subparser.add_argument("-H", "--host", dest="hostname", type=str, default="127.0.0.1") + subparser.add_argument("-P", "--port", dest="port", type=int, default=57823) + subparser.add_argument("-cc", "--certificate", dest="certificate", type=Path, required=False) + + subsubparsers = subparser.add_subparsers(dest="action") + action.load_parse(subsubparsers) diff --git a/mains/role/client/run.py b/mains/role/client/run.py new file mode 100644 index 0000000..ce781da --- /dev/null +++ b/mains/role/client/run.py @@ -0,0 +1,13 @@ +import argparse + +from . import action + + +def run(parser: argparse.ArgumentParser, arguments: argparse.Namespace): + match arguments.action: + case "vote": + action.vote.run(parser, arguments) + + # if the subcommand is not known, show the help + case _: + parser.print_usage() diff --git a/mains/role/machine/__init__.py b/mains/role/machine/__init__.py new file mode 100644 index 0000000..05e733e --- /dev/null +++ b/mains/role/machine/__init__.py @@ -0,0 +1,2 @@ +from .argparse import load_parse +from .run import run diff --git a/mains/role/machine/argparse.py b/mains/role/machine/argparse.py new file mode 100644 index 0000000..b193ea2 --- /dev/null +++ b/mains/role/machine/argparse.py @@ -0,0 +1,11 @@ +import argparse +from pathlib import Path + + +def load_parse(subparsers): + subparser: argparse.ArgumentParser = subparsers.add_parser("machine") + + subparser.add_argument("-H", "--host", dest="hostname", type=str, default="0.0.0.0") + subparser.add_argument("-p", "--port", dest="port", type=int, default=57823) + subparser.add_argument("-cc", "--certificate", dest="certificate", type=Path, required=True) + subparser.add_argument("-ck", "--private-key", dest="private_key", type=Path, required=True) diff --git a/mains/role/machine/run.py b/mains/role/machine/run.py new file mode 100644 index 0000000..2c8f6b5 --- /dev/null +++ b/mains/role/machine/run.py @@ -0,0 +1,23 @@ +import argparse +import json + + +def run(parser: argparse.ArgumentParser, arguments: argparse.Namespace): + import ssl + import socket + + context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_SERVER) + context.load_cert_chain(arguments.certificate, arguments.private_key) + + with ( + socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock_server, + context.wrap_socket(sock_server, server_side=True) as ssl_sock_server + ): + ssl_sock_server.bind((arguments.hostname, arguments.port)) + ssl_sock_server.listen(5) + + while True: + print("waiting for a connection...") + connect, address = ssl_sock_server.accept() + data = json.loads(connect.recv()) + print(data) diff --git a/mains/server.py b/mains/server.py deleted file mode 100644 index 2c5977d..0000000 --- a/mains/server.py +++ /dev/null @@ -1,24 +0,0 @@ -import argparse - - -arg_parser = argparse.ArgumentParser() - -arg_parser.add_argument("-H", "--host", dest="hostname", type=str, default="0.0.0.0") -arg_parser.add_argument("-p", "--port", dest="port", type=int, default=57823) - -arguments = arg_parser.parse_args() - - -if arguments: - import ssl - import socket - - context = ssl.create_default_context() - - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock_server: - sock_server.bind((arguments.hostname, arguments.port)) - sock_server.listen(5) - - with context.wrap_socket(sock_server, server_side=True) as ssl_sock_server: - data = ssl_sock_server.recv() - print(data) diff --git a/requirements.txt b/requirements.txt index 0d38bc5..488c3aa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -cryptography +cryptography \ No newline at end of file diff --git a/source/Card.py b/source/Card.py index a261724..5a7dad7 100644 --- a/source/Card.py +++ b/source/Card.py @@ -10,9 +10,7 @@ class Card: Represent the card of an elector. """ - def __init__(self, name: str, pin: str): - self.name = name - + def __init__(self, pin: str): self._private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, diff --git a/source/Machine.py b/source/Machine.py index 32690e2..9a27699 100644 --- a/source/Machine.py +++ b/source/Machine.py @@ -167,8 +167,9 @@ class Machine: if elector is None: print("L’électeur n’est pas inscrit dans la liste électorale.") return False - print(f"L’électeur {elector.name} vote par procuration.") - print(f"L’électeur {elector.name} peut voter.") + print(f"L’électeur {elector.name} est sur la liste électorale et vote par procuration.") + else: + print(f"L’électeur {elector.name} est sur la liste électorale.") # Is the fingerprint matching? if not self.check_fingerprint(elector, fingerprint): @@ -176,7 +177,7 @@ class Machine: return False # L’électeur est authentifié. - print(f"Électeur {elector.name} authentifié") + print(f"L’électeur {elector.name} est authentifié") return True def vote(self, card: Card, vote: str) -> bool: @@ -256,7 +257,7 @@ class Machine: self._vote_list.append(vote) random.shuffle(self._vote_list) - print(f"Vote de {elector.name} comptabilisé!") + print(f"Vote de {elector.name} comptabilisé(e)!") return True def cloture_du_vote(self) -> tuple[list[str], bytes]: diff --git a/source/__main__.py b/source/__main__.py index f9663f5..c31659b 100644 --- a/source/__main__.py +++ b/source/__main__.py @@ -55,6 +55,3 @@ machine_certificate = builder.sign(admin_private_key, algorithm=hashes.SHA256()) print(machine_certificate) # check that the machine machine_certificate.verify_directly_issued_by(admin_certificate) - - -# diff --git a/source/models/Proof.py b/source/models/Proof.py index 16a4772..e111da9 100644 --- a/source/models/Proof.py +++ b/source/models/Proof.py @@ -8,7 +8,7 @@ from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey class Proof: date: datetime - public_key_votant: RSAPublicKey + public_key_elector: RSAPublicKey public_key_mandataire: RSAPublicKey proof_signature: bytes diff --git a/source/wtf/Electeur.py b/source/wtf/Electeur.py deleted file mode 100644 index 1352c99..0000000 --- a/source/wtf/Electeur.py +++ /dev/null @@ -1,16 +0,0 @@ -class Electeur: - def __init__(self, nom, prenom, empreinte_digitale): - self.nom = nom - self.prenom = prenom - self.empreinte_digitale = empreinte_digitale - self.carte_election = None - self.code_pin = None - - def recevoir_carte_election(self, carte_election): - self.carte_election = carte_election - - def definir_code_pin(self, code_pin): - self.code_pin = code_pin - - def authentifier(self): - return self.carte_election.est_authentique(self.empreinte_digitale, self.code_pin) diff --git a/source/wtf/ExempleAutiliser.py b/source/wtf/ExempleAutiliser.py deleted file mode 100644 index 8cdc0d2..0000000 --- a/source/wtf/ExempleAutiliser.py +++ /dev/null @@ -1,48 +0,0 @@ -from source.Card import Card -from source.wtf.Electeur import Electeur -from source.wtf.Machine2 import Machine2 - -if __name__ == "__main__": - # Création d'un électeur - electeur1 = Electeur("Alice", "Dupont", "empreinte_alice123") - electeur2 = Electeur("Bob", "Martin", "empreinte_bob456") - - # Création de cartes d'élection pour les électeurs - carte1 = Card(electeur1, "cle_publique_alice") - carte2 = Card(electeur2, "cle_publique_bob") - - # Activation des cartes avec un code PIN - carte1.activer("cle_privee_chiffree_alice", "code_pin_chiffre_alice") - carte2.activer("cle_privee_chiffree_bob", "code_pin_chiffre_bob") - - # Attribution des cartes aux électeurs - electeur1.recevoir_carte_election(carte1) - electeur2.recevoir_carte_election(carte2) - - # Définition des codes PIN - electeur1.definir_code_pin("1234") - electeur2.definir_code_pin("5678") - - # Création d'une machine à voter avec un certificat - certificat_machine = "certificat_de_la_machine" - machine = Machine2(certificat_machine) - - # Chargement de la liste électorale dans la machine - liste_electorale = { - "cle_publique_alice": electeur1.nom, - "cle_publique_bob": electeur2.nom - } - machine.charger_liste_electorale(liste_electorale) - - # Authentification et vote d'un électeur - if machine.authentifier_electeur(electeur1): - preuve_vote = { - "vote": "Choix d'Alice", - "preuve": "Preuve de vote d'Alice" - } - machine.enregistrer_vote(preuve_vote) - - # Fin du vote et publication des résultats - machine.fin_de_vote() - resultats = machine.publier_resultats() - print("Résultats publiés:", resultats) diff --git a/source/wtf/Machine2.py b/source/wtf/Machine2.py deleted file mode 100644 index fc4c70f..0000000 --- a/source/wtf/Machine2.py +++ /dev/null @@ -1,23 +0,0 @@ -class Machine2: - def __init__(self, certificat): - self.certificat = certificat - self.liste_electorale = {} - self.bdd_votes = [] - self.bdd_preuves = [] - - def charger_liste_electorale(self, liste_electorale): - self.liste_electorale = liste_electorale - - def authentifier_electeur(self, electeur): - return electeur.authentifier() and electeur.carte_election.cle_publique in self.liste_electorale - - def enregistrer_vote(self, preuve_vote): - self.bdd_votes.append(preuve_vote['vote']) - self.bdd_preuves.append(preuve_vote) - - def publier_resultats(self): - return self.bdd_votes - - def fin_de_vote(self): - # Bloquer les nouveaux votes - self.bloque = True diff --git a/source/wtf/__init__.py b/source/wtf/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/exemple1.ipynb b/tests/exemple1.ipynb deleted file mode 100644 index 54f657b..0000000 --- a/tests/exemple1.ipynb +++ /dev/null @@ -1,37 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "initial_id", - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/tests/exemple1.py b/tests/exemple1.py index 1182254..0face7b 100644 --- a/tests/exemple1.py +++ b/tests/exemple1.py @@ -1,61 +1,82 @@ -import hashlib -from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.asymmetric import rsa -from cryptography.hazmat.primitives.asymmetric import padding - from source.Card import Card from source.models.Elector import Elector -#from source.Certificate import Certificate from source.Machine import Machine +# Vote électronique + +# 3 personnes + +alice = { + "name": "Alice", + "password": "6060", + "empreinte": "empreinteA", + "vote": "Riri", +} + +bob = { + "name": "Bob", + "password": "0100", + "empreinte": "empreinteB", + "vote": "Toto", +} + +eve = { + "name": "Eve", + "password": "008", + "empreinte": "empreinteE", + "vote": "Jack", +} + +personnes = [alice, bob, eve] + # Création des cartes -alice_card = Card("Alice", "6060") -bob_card = Card("Bob", "0100") -eve_card = Card("Eve", "0008") -print(f"carte alice pubkey: {alice_card.public_key}") -print("Cartes d’élections créent") - -input() +alice["card"] = Card(alice["password"]) +bob["card"] = Card(bob["password"]) +eve["card"] = Card(eve["password"]) +print(f"Liste de cartes : {[personne['card'] for personne in personnes]}") +print("Cartes d’élections créées.") +print() # Création de la liste électorale # Eve peut voter pour Alice -alice_elector = Elector(name="Alice", - public_key_elector=alice_card.public_key, - fingerprint_elector="empreinteA", - public_key_mandataire=eve_card.public_key, - fingerprint_mandataire="empreinteE") -bob_elector = Elector("Bob", bob_card.public_key, "empreinteB") -eve_elector = Elector("Eve", eve_card.public_key, "empreinteE") -emerging_list = [alice_elector, bob_elector, eve_elector] -print(f"alice name: {alice_elector.name}") -print(f"alice pubkey: {alice_elector.public_key_elector}") -print(f"alice pubkey mandataire: {alice_elector.public_key_mandataire}") -print(f"alice empreinte: {alice_elector.hashed_fingerprint_elector}") -print(f"alice empreinte mandataire: {alice_elector.hashed_fingerprint_mandataire}") -print(f"liste d’émargement: {emerging_list}") -print("Liste électorale crée.") +alice_elector = Elector(name=alice["name"], + public_key_elector=alice["card"].public_key, fingerprint_elector=alice["empreinte"], + public_key_mandataire=eve["card"].public_key, fingerprint_mandataire=eve["empreinte"]) +bob_elector = Elector(name=bob["name"], + public_key_elector=bob["card"].public_key, fingerprint_elector=bob["empreinte"]) -input() +emerging_list = [alice_elector, bob_elector] +print(f"Liste d’émargement: {emerging_list}") +print("Liste électorale créée.") +print() # Création de la machine machine = Machine(emerging_list) -print(f"machine pubkey : {machine._public_key.public_bytes()}") -print("Machine pour voter crée") +print(f"Machine pubkey : {machine.public_key}") +print("Machine pour voter créée") +print() -input() +# Votes des personnes +alice["password"] = "fleur" +for personne in personnes: + # Authentification + print() + print(f"La personne {personne["name"]} s’authentifie avec le mdp {personne["password"]} et l’empreinte {personne["empreinte"]}.") + if not machine.authenticate(personne["card"], personne["password"], personne["empreinte"]): + continue - -# Authentification - -# Vote + # Vote + print() + print(f"La personne {personne["name"]} va voter pour {personne["vote"]}") + if not machine.vote(personne["card"], personne["vote"]): + continue # Publication des résultats -#Machine.authenticate(Alice_card, 6060, "azerty") - - -#Machine.vote(Alice_card) \ No newline at end of file +votes, sig_votes = machine.cloture_du_vote() +print() +print(votes) diff --git a/tests/exemple2.py b/tests/exemple2.py new file mode 100644 index 0000000..1fe31b7 --- /dev/null +++ b/tests/exemple2.py @@ -0,0 +1,2 @@ + +# Vote à distance