22
33from pathlib import Path
44
5- from fastapi import APIRouter , HTTPException
5+ from fastapi import APIRouter , Depends , HTTPException
66from pydantic import BaseModel , Field
77
8+ from hybrid_pki .api .security import require_mutation_access
89from hybrid_pki .classical .keygen import (
910 generate_ecdsa_private_key ,
1011 save_pem_file ,
@@ -68,7 +69,7 @@ class HybridCertificateDemoRequest(BaseModel):
6869 )
6970 classical_algorithm : str = Field (default = "ECDSA-P256" )
7071 pqc_signature_algorithm : str = Field (default = "ML-DSA-65" )
71- days_valid : int = Field (default = 365 , ge = 1 )
72+ days_valid : int = Field (default = 365 , ge = 1 , le = 397 )
7273
7374
7475class HybridCertificateVerifyRequest (BaseModel ):
@@ -120,7 +121,7 @@ def hybrid_status():
120121 }
121122
122123
123- @router .post ("/ca/create-demo" )
124+ @router .post ("/ca/create-demo" , dependencies = [ Depends ( require_mutation_access )] )
124125def create_hybrid_demo_ca ():
125126 """
126127 Create demo Hybrid CA material.
@@ -183,7 +184,7 @@ def create_hybrid_demo_ca():
183184 ) from exc
184185
185186
186- @router .post ("/certificates/create-demo" )
187+ @router .post ("/certificates/create-demo" , dependencies = [ Depends ( require_mutation_access )] )
187188def create_hybrid_demo_certificate (request : HybridCertificateDemoRequest ):
188189 """
189190 Create and sign a demo hybrid certificate.
@@ -335,7 +336,7 @@ def verify_hybrid_demo_certificate(request: HybridCertificateVerifyRequest):
335336 ) from exc
336337
337338
338- @router .post ("/handshake/simulate" )
339+ @router .post ("/handshake/simulate" , dependencies = [ Depends ( require_mutation_access )] )
339340def simulate_hybrid_handshake (request : HybridHandshakeRequest ):
340341 """
341342 Simulate a hybrid handshake using X25519 + ML-KEM.
@@ -361,6 +362,7 @@ def simulate_hybrid_handshake(request: HybridHandshakeRequest):
361362 server_pqc_secret_key = server_keys .pqc_secret_key ,
362363 pqc_ciphertext = client_result .pqc_ciphertext ,
363364 pqc_algorithm = server_keys .pqc_algorithm ,
365+ server_pqc_public_key = server_keys .pqc_public_key ,
364366 )
365367
366368 secrets_match = server_secret == client_result .hybrid_secret
@@ -373,6 +375,8 @@ def simulate_hybrid_handshake(request: HybridHandshakeRequest):
373375 "kdf" : "HKDF-SHA256" ,
374376 },
375377 "secrets_match" : secrets_match ,
378+ "authenticated" : False ,
379+ "security_note" : "Transcript-bound key establishment; peer authentication is not provided." ,
376380 "hybrid_secret_length" : len (server_secret ),
377381 "pqc_ciphertext_length" : len (client_result .pqc_ciphertext ),
378382 "server_classical_public_key_length" : len (
0 commit comments