Skip to content

Commit

Permalink
sync (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
jschlyter authored Dec 17, 2024
1 parent dabf57b commit 2d4778c
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 17 deletions.
9 changes: 5 additions & 4 deletions nodeman/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,11 @@ def command_create(args: argparse.Namespace) -> NodeBootstrapInformation:

create_response = response.json()
name = create_response["name"]
secret = create_response["secret"]
logging.info("Created node with name=%s secret=%s", name, secret)

return NodeBootstrapInformation(name=name, secret=secret)
logging.debug("Response: %s", json.dumps(create_response, indent=4))
logging.info("Created node with name=%s", name)

return NodeBootstrapInformation(name=name, key=create_response["key"])


def command_delete(args: argparse.Namespace) -> None:
Expand Down Expand Up @@ -209,7 +210,7 @@ def command_enroll(args: argparse.Namespace) -> NodeConfiguration:
if args.create:
node_bootstrap_information = command_create(args)
name = node_bootstrap_information.name
secret = node_bootstrap_information.secret
secret = node_bootstrap_information.key.k
else:
name = args.name
secret = args.secret
Expand Down
8 changes: 8 additions & 0 deletions nodeman/jose.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ class PublicOKP(BaseJWK):
x: Base64UrlString


class PrivateSymmetric(BaseJWK):
"""JWK: Private symmetric key"""

kty: Annotated[str, StringConstraints(pattern=r"^oct$")]
k: Base64UrlString
alg: str | None = None


PublicJwk = PublicRSA | PublicEC | PublicOKP


Expand Down
4 changes: 2 additions & 2 deletions nodeman/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pydantic.types import AwareDatetime

from .db_models import TapirNode
from .jose import PublicJwk, public_key_factory
from .jose import PrivateSymmetric, PublicJwk, public_key_factory
from .settings import MqttUrl

MAX_REQUEST_AGE = 300
Expand Down Expand Up @@ -65,7 +65,7 @@ class NodeCollection(BaseModel):

class NodeBootstrapInformation(BaseModel):
name: str = Field(title="Node name")
secret: str = Field(title="Enrollment secret")
key: PrivateSymmetric = Field(title="Enrollment JWK")


class NodeCertificate(BaseModel):
Expand Down
10 changes: 7 additions & 3 deletions nodeman/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,14 @@ def find_node(name: str) -> TapirNode:
status.HTTP_201_CREATED: {"model": NodeBootstrapInformation},
},
tags=["backend"],
response_model_exclude_none=True,
)
async def create_node(
request: Request, username: Annotated[str, Depends(get_current_username)], name: str | None = None
) -> NodeBootstrapInformation:
secret = JWK.generate(kty="oct", size=256).k
"""Create node"""

node_enrollment_key = JWK.generate(kty="oct", size=256, alg="HS256")
domain = request.app.settings.nodes.domain

if name is None:
Expand All @@ -71,12 +74,13 @@ async def create_node(
logging.warning("Explicit node name %s not acceptable", name, extra={"nodename": name})
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail="Invalid node name")

node_secret = TapirNodeSecret(name=node.name, secret=secret).save()
TapirNodeSecret(name=node.name, secret=node_enrollment_key.k).save()

nodes_created.add(1, {"creator": username})

logging.info("%s created node %s", username, node.name, extra={"username": username, "nodename": node.name})
return NodeBootstrapInformation(name=node.name, secret=node_secret.secret)

return NodeBootstrapInformation(name=node.name, key=node_enrollment_key.export(as_dict=True, private_key=True))


@router.get(
Expand Down
19 changes: 11 additions & 8 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def _test_enroll(data_key: JWK, x509_key: PrivateKey, requested_name: str | None
assert response.status_code == status.HTTP_201_CREATED
create_response = response.json()
name = create_response["name"]
secret = create_response["secret"]
secret = create_response["key"]["k"]
if requested_name:
assert name == requested_name
logging.info("Got name=%s secret=%s", name, secret)
Expand All @@ -99,8 +99,8 @@ def _test_enroll(data_key: JWK, x509_key: PrivateKey, requested_name: str | None
#####################
# Enroll created node

hmac_key = JWK(kty="oct", k=secret)
hmac_alg = "HS256"
hmac_key = JWK(**create_response["key"])
hmac_alg = hmac_key.alg

data_alg = jwk_to_alg(data_key)

Expand Down Expand Up @@ -276,8 +276,10 @@ def test_enroll_bad_hmac_signature() -> None:
create_response = response.json()
name = create_response["name"]

hmac_key = JWK.generate(kty="oct")
hmac_alg = "HS256"
hmac_key = JWK.generate(kty="oct", size=256, alg="HS256")
hmac_alg = hmac_key.alg

assert hmac_alg == "HS256"

data_key = JWK.generate(kty=kty, crv=crv)
data_alg = jwk_to_alg(data_key)
Expand Down Expand Up @@ -321,10 +323,11 @@ def test_enroll_bad_data_signature() -> None:
assert response.status_code == status.HTTP_201_CREATED
create_response = response.json()
name = create_response["name"]
secret = create_response["secret"]

hmac_key = JWK(kty="oct", k=secret)
hmac_alg = "HS256"
hmac_key = JWK(**create_response["key"])
hmac_alg = hmac_key.alg

assert hmac_alg == "HS256"

data_key = JWK.generate(kty=kty, crv=crv)
bad_data_key = JWK.generate(kty=kty, crv=crv)
Expand Down

0 comments on commit 2d4778c

Please sign in to comment.