Skip to content
Snippets Groups Projects
Commit 66152b93 authored by Valentin Rigal's avatar Valentin Rigal
Browse files

Remove other ponos modules

parent 4f2b5dd8
No related branches found
No related tags found
No related merge requests found
This commit is part of merge request !2233. Comments created here will be created in the context of that merge request.
import logging
import os.path
from os import urandom
from cryptography.exceptions import InvalidKey
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.hashes import SHA256
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives.serialization import Encoding, NoEncryption, PrivateFormat, load_pem_private_key
from django.conf import settings
logger = logging.getLogger(__name__)
def gen_nonce(size=16):
"""
Generates a simple nonce
Number size si defined in bytes (defaults to 128 bits)
https://cryptography.io/en/latest/glossary/#term-nonce
"""
return urandom(size)
def gen_private_key(dest_path) -> None:
"""
Generates an elliptic curve private key and saves it to a local file in PEM format.
See https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/
:param dest_path: Path to save the new key to.
:type dest_path: str or path-like object
"""
key = ec.generate_private_key(
ec.SECP384R1(),
default_backend(),
)
with open(dest_path, "wb") as f:
f.write(
key.private_bytes(
Encoding.PEM,
PrivateFormat.PKCS8,
NoEncryption(),
)
)
def load_private_key():
"""
Load an existing private key from the path given in the ``PONOS_PRIVATE_KEY`` setting.
:returns: An elliptic curve private key instance.
:raises Exception: When the Django ``DEBUG`` setting is set to False
and the server is misconfigured or the key is not found or invalid
"""
def _abort(message):
"""
On Debug, be nice with developers, just display a warning
On Prod, simply crash
"""
if getattr(settings, "DEBUG", False):
logger.warning("Please fix your security configuration: {}".format(message))
else:
raise Exception(message)
if not getattr(settings, "PONOS_PRIVATE_KEY", None):
return _abort("Missing setting PONOS_PRIVATE_KEY")
if not os.path.exists(settings.PONOS_PRIVATE_KEY):
return _abort(
"Invalid PONOS_PRIVATE_KEY path: {}".format(settings.PONOS_PRIVATE_KEY)
)
with open(settings.PONOS_PRIVATE_KEY, "rb") as f:
key = load_pem_private_key(
f.read(),
password=None,
backend=default_backend(),
)
assert isinstance(
key, ec.EllipticCurvePrivateKey
), "Private {} key is not an ECDH key".format(settings.PONOS_PRIVATE_KEY)
return key
def check_agent_key(agent_public_key, agent_derivation, seed) -> bool:
"""
Authenticates a new agent using its public key and a derivation
of its private key with the server's public key.
:param agent_public_key: An agent's public key.
:type agent_public_key: cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey
:param agent_derivation bytes: A bytestring representing the server's public key
derived with the agent's private key using HKDF and holding a :class:`~`onos.models.Farm`'s seed.
:param seed str: The expected farm seed.
"""
shared_key = load_private_key().exchange(ec.ECDH(), agent_public_key)
hkdf = HKDF(
algorithm=SHA256(),
backend=default_backend(),
length=32,
salt=None,
info=seed.encode("utf-8"),
)
try:
hkdf.verify(shared_key, agent_derivation)
return True
except InvalidKey:
return False
......@@ -9,7 +9,6 @@ import enumfields.fields
from django.contrib.postgres.operations import HStoreExtension
from django.db import migrations, models
import arkindex.ponos.keys
import arkindex.ponos.models
import arkindex.project.fields
import arkindex.project.validators
......@@ -77,7 +76,7 @@ class Migration(migrations.Migration):
fields=[
("id", models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
("name", models.CharField(max_length=250, unique=True)),
("nonce", models.BinaryField(default=arkindex.ponos.keys.gen_nonce, max_length=16)),
("nonce", models.BinaryField(default=arkindex.ponos.models.gen_nonce, max_length=16)),
("content", models.BinaryField(editable=True)),
],
),
......
......@@ -3,6 +3,7 @@ import os.path
import random
import uuid
from datetime import timedelta
from os import urandom
from botocore.exceptions import ClientError
from django.conf import settings
......@@ -15,7 +16,6 @@ from django.urls import reverse
from django.utils import timezone
from enumfields import Enum, EnumField
from arkindex.ponos.keys import gen_nonce
from arkindex.ponos.managers import FarmManager, TaskManager
from arkindex.project.aws import S3FileMixin
from arkindex.project.validators import MaxValueValidator
......@@ -32,6 +32,15 @@ def generate_seed() -> str:
return "{:064x}".format(random.getrandbits(256))
def gen_nonce(size=16):
"""
Generates a simple nonce
Number size si defined in bytes (defaults to 128 bits)
https://cryptography.io/en/latest/glossary/#term-nonce
"""
return urandom(size)
class Farm(models.Model):
"""
A group of agents, whose ID and seed can be used to register new agents
......
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
from rest_framework.renderers import BaseRenderer
class PublicKeyPEMRenderer(BaseRenderer):
"""
A Django REST Framework renderer to serialize public keys as PEM.
"""
media_type = "application/x-pem-file"
format = "pem"
def render(self, data: ec.EllipticCurvePublicKey, *args, **kwargs) -> bytes:
assert isinstance(data, ec.EllipticCurvePublicKey)
return data.public_bytes(
encoding=Encoding.PEM,
format=PublicFormat.SubjectPublicKeyInfo,
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment