Public Key Infrastructure (PKI) per sistemi ITS (Intelligent Transportation Systems) conforme agli standard ETSI
- Panoramica
- Installazione Rapida
- Avvio del Sistema
- Architettura
- Entità PKI
- REST API
- Formato Certificati
- Testing
- Documentazione
SecureRoad-PKI è un'implementazione production-ready di una Public Key Infrastructure per sistemi V2X (Vehicle-to-Everything) conforme agli standard ETSI TS 102941 e ETSI TS 103097, con supporto completo ASN.1 OER encoding.
✅ Conformità Standard ETSI: Implementazione completa ETSI TS 102941 (Trust & Privacy Management) e TS 103097 (Certificate Formats)
✅ ASN.1 OER Nativo: Encoding/decoding certificati in formato ASN.1 binario secondo IEEE 1609.2
✅ REST API Production-Ready: 8 blueprint con autenticazione, rate limiting, CORS
✅ Gestione Certificati Completa: Enrollment, Authorization, Revoca con supporto CRL/CTL Delta
✅ Privacy-Preserving: Butterfly key expansion per unlinkability (batch 20 AT)
✅ Testing Robusto: 130+ test automatici con coverage completo
✅ Dashboard Web Interattiva: Monitoraggio real-time e gestione delle entità
✅ Auto-Start System: Setup automatico multi-entità con processi in background
- 16600+ righe di codice Python
- 130+ test automatici (100% passing)
- 8 REST API blueprints completamente funzionanti
- 5 entità PKI: RootCA, EA, AA, TLM, ITS-S
- ASN.1 OER compliant secondo ETSI TS 103097
- ~95% completamento generale
- Python 3.8+
- pip
- Windows PowerShell (per Windows) o Bash (per Linux/Mac)
# Clone repository
git clone https://github.com/Mattyilmago/SecureRoads_PKI.git
cd SecureRoads_PKI
# Crea virtual environment (raccomandato)
python -m venv .venv
.venv\Scripts\Activate.ps1 # Windows PowerShell
# source .venv/bin/activate # Linux/Mac
# Installa dipendenze
pip install -r requirements.txt💡 Gestione Automatica delle Porte:
Il sistema assegna automaticamente le porte senza conflitti:
- RootCA: Porta fissa 5999
- EA (Enrollment Authorities): Range 5000-5019 (max 20 istanze)
- AA (Authorization Authorities): Range 5020-5039 (max 20 istanze)
- TLM: Porta fissa 5050
- Dashboard: Porta 8080
Non è necessario specificare manualmente le porte: server.py trova automaticamente la prima porta disponibile nel range dedicato.
SecureRoad-PKI offre multiple opzioni di avvio a seconda delle tue esigenze:
Avvia RootCA, TLM e il server web della dashboard con un solo comando:
# Windows
.\start_dashboard.ps1
# Apri nel browser
# http://localhost:8080/pki_dashboard.htmlCosa include:
- ✅ RootCA (porta 5999) - Background process
- ✅ TLM (porta 5050) - Background process
- ✅ Dashboard HTTP Server (porta 8080)
- ✅ Health check automatico
- ✅ Processi mantengono attivi in background
Per fermare tutto:
# Premi Ctrl+C per fermare la dashboard
# Poi pulisci i job in background:
Get-Job | Stop-Job
Get-Job | Remove-JobAvvia singole entità per testing o deployment personalizzato:
# RootCA (Trust Anchor)
python server.py --entity RootCA
# Enrollment Authority
python server.py --entity EA --id EA_001
# Authorization Authority
python server.py --entity AA --id AA_001
# Trust List Manager
python server.py --entity TLM --id TLM_MAIN
# ITS Station (per testing)
python -m entities.its_stationCrea e avvia automaticamente più entità PKI con un singolo comando:
# Crea e avvia 1 EA + 1 AA + TLM + RootCA (se porte disponibili)
python server.py --ea 1 --aa 1
# Crea e avvia 3 EA + 2 AA + TLM + RootCA
python server.py --ea 3 --aa 2
# Crea solo EA senza AA
python server.py --ea 5
# Crea con nomi personalizzati
python server.py --ea 2 --aa 1 --ea-names "EA_Prod,EA_Test"Cosa fa automaticamente:
- ✅ Genera configurazione in
entity_configs.json - ✅ Assegna porte automaticamente senza conflitti
- ✅ Crea TLM se porta 5050 libera
- ✅ Crea RootCA se porta 5999 libera
- ✅ Avvia tutte le entità in background
- ✅ Salva log in
logs/directory
Per fermare tutto:
# Windows
.\stop_all.ps1
# Linux/Mac
./scripts/stop_all.shPer eseguire test completi del sistema:
# Avvia il tester interattivo (avvia automaticamente le entità necessarie)
python examples/interactive_pki_tester.py
# Oppure usa entità già avviate
python examples/interactive_pki_tester.py --no-startSecureRoad-PKI segue i principi SOLID e utilizza design patterns moderni:
┌─────────────────────────────────────────────────────────────┐
│ Root CA │
│ - Self-signed root certificate (ASN.1 OER) │
│ - Firma certificati subordinati (EA, AA) │
│ - Gestione CRL tramite CRLManager │
└────────────────┬────────────────────────────────────────────┘
│
┌────────┴────────┐
│ │
┌───────▼──────┐ ┌──────▼────────┐
│ EA │ │ AA │
│ Enrollment │ │Authorization │
│ Authority │ │ Authority │
└──────┬───────┘ └───────┬───────┘
│ │
│ │
└───────┬───────────┘
│
┌──────▼──────┐
│ TLM │
│Trust List │
│ Manager │
└─────────────┘
│
┌──────▼──────┐
│ ITS-S │
│ Vehicles │
└─────────────┘
SecureRoad-PKI/
├── entities/ # Entità PKI principali
│ ├── root_ca.py # Root Certificate Authority
│ ├── enrollment_authority.py # Enrollment Authority
│ ├── authorization_authority.py # Authorization Authority
│ └── its_station.py # ITS Station (veicoli)
├── managers/ # Manager di sistema
│ ├── crl_manager.py # Gestione CRL (Certificate Revocation Lists)
│ └── trust_list_manager.py # Gestione CTL (Certificate Trust Lists)
├── protocols/ # Layer protocollo ETSI
│ ├── certificates/ # Encoding certificati ASN.1 OER
│ ├── messages/ # Encoding messaggi ETSI
│ ├── core/ # Funzioni crypto core
│ └── security/ # Butterfly expansion, PoP
├── api/ # REST API Layer
│ ├── blueprints/ # Flask blueprints
│ │ ├── enrollment_bp.py
│ │ ├── authorization_bp.py
│ │ ├── trust_list_bp.py
│ │ ├── crl_bp.py
│ │ ├── rootca_bp.py
│ │ ├── monitoring_bp.py
│ │ ├── management_bp.py
│ │ └── stats_bp.py
│ └── middleware/ # Auth, rate limiting, CORS
├── services/ # Business logic services
│ ├── aa_key_manager.py # Gestione chiavi AA
│ ├── at_scheduler.py # Scheduling Authorization Tickets
│ └── ec_validator.py # Validazione Enrollment Certificates
├── config/ # Configurazione centralizzata
│ └── pki_config.py # PKIPaths, costanti
├── utils/ # Utilities condivise
│ ├── pki_paths.py # Path management (DRY)
│ ├── pki_io.py # File I/O operations
│ ├── logger.py # Logging centralizzato
│ └── metrics.py # Metrics collection
└── pki_data/ # Dati runtime
├── root_ca/
├── ea/
├── aa/
├── tlm/
└── itss/
Classe: entities.root_ca.RootCA
Responsabilità:
- Generazione certificato root self-signed in formato ASN.1 OER
- Firma certificati subordinati (EA, AA)
- Gestione revoche tramite
CRLManager - Archiviazione certificati subordinati
Metodi Principali:
# Inizializzazione (usa config.PKI_PATHS.ROOT_CA automaticamente)
root_ca = RootCA(base_dir=None)
# Firma certificato subordinato
subordinate_cert_asn1 = root_ca.sign_subordinate_certificate(
public_key=public_key,
subject_attributes={"id": "EA_001", "name": "Highway EA"},
validity_period=timedelta(days=3650)
)
# Revoca certificato
root_ca.revoke_certificate(
certificate_id="EA_001_cert_hash",
reason=CRLReason.KEY_COMPROMISE
)
# Pubblica CRL
root_ca.crl_manager.publish_full_crl()Percorsi Dati:
- Certificato:
pki_data/root_ca/certificates/root_ca_certificate.oer - Chiave privata:
pki_data/root_ca/private_keys/root_ca_key.key - CRL:
pki_data/root_ca/crl/root_ca_crl.pem
Classe: entities.enrollment_authority.EnrollmentAuthority
Responsabilità:
- Emissione Enrollment Certificates (EC) in formato ASN.1 OER
- Validazione Proof of Possession nelle EnrollmentRequest
- Pubblicazione automatica CRL (Full e Delta)
- Registrazione automatica presso TLM
Metodi Principali:
# Inizializzazione
ea = EnrollmentAuthority(
root_ca=root_ca,
ea_id="EA_001", # generato automaticamente se None
base_dir=None, # usa config.PKI_PATHS.EA
tlm=tlm # opzionale, per auto-registration
)
# Processa richiesta ETSI (ASN.1 OER)
response_asn1 = ea.process_enrollment_request_etsi(
request_asn1_bytes=request_bytes
)
# Emissione certificato
ec_asn1 = ea.issue_enrollment_certificate(
its_id="VEHICLE_001",
public_key=vehicle_public_key,
validity_hours=8760 # 1 anno
)
# Revoca certificato
ea.revoke_certificate(
certificate_id="hashed_id8_hex",
reason=CRLReason.AFFILIATION_CHANGED
)Endpoint API:
POST /api/enrollment/request- Enrollment request ETSIGET /api/enrollment/certificate/<id>- Download certificatoGET /api/enrollment/crl- Download CRL
Classe: entities.authorization_authority.AuthorizationAuthority
Responsabilità:
- Emissione Authorization Tickets (AT) per veicoli ITS-S
- Validazione Enrollment Certificates tramite
ECValidator - Supporto Butterfly Key Expansion per batch AT (privacy)
- Gestione revoche tramite
CRLManager
Metodi Principali:
# Inizializzazione
aa = AuthorizationAuthority(
root_ca=root_ca,
tlm=tlm,
crl_manager=root_ca.crl_manager,
aa_id="AA_001",
base_dir=None
)
# Processa richiesta ETSI (ASN.1 OER)
response_asn1 = aa.process_authorization_request_etsi(
request_asn1_bytes=request_bytes
)
# Emissione singolo AT
at_asn1 = aa.issue_authorization_ticket(
its_id="VEHICLE_001",
enrollment_cert=ec_bytes,
permissions=["traffic_info", "emergency"],
validity_hours=168 # 1 settimana
)
# Butterfly batch (20 AT unlinkable)
tickets = aa.issue_butterfly_authorization_tickets(
its_id="VEHICLE_001",
enrollment_cert=ec_bytes,
permissions=["traffic_info"],
batch_size=20
)Endpoint API:
POST /api/authorization/request- Authorization request ETSIPOST /api/authorization/request/butterfly- Butterfly batch modeGET /api/authorization/certificate- Download AA certificate
Classe: managers.trust_list_manager.TrustListManager
Responsabilità:
- Gestione trust anchors (EA, AA, subordinate CAs)
- Pubblicazione Full CTL e Delta CTL in formato ASN.1 OER
- Generazione Link Certificates per trust chain navigation
- Validazione catene di fiducia per ITS-S
Metodi Principali:
# Inizializzazione
tlm = TrustListManager(
root_ca=root_ca,
tlm_id="TLM_MAIN",
base_dir=None, # usa config.PKI_PATHS.TLM_MAIN
crl_manager=root_ca.crl_manager
)
# Aggiungi trust anchor
tlm.add_trust_anchor(
entity_id="EA_001",
certificate_asn1=ea_cert_bytes,
entity_type="EA"
)
# Rimuovi trust anchor
tlm.remove_trust_anchor(certificate_id="hashed_id8_hex")
# Pubblica Full CTL
tlm.publish_full_ctl()
# Pubblica Delta CTL
tlm.publish_delta_ctl()
# Verifica fiducia
is_trusted = tlm.is_trusted(certificate_asn1=cert_bytes)Endpoint API:
GET /api/trust_list/full- Download Full CTLGET /api/trust_list/delta- Download Delta CTLGET /api/trust_list/link_certificates- Download Link Certificates bundle
Classe: entities.its_station.ITSStation
Responsabilità:
- Richiesta Enrollment Certificates (EC)
- Richiesta Authorization Tickets (AT)
- Invio/ricezione messaggi V2X firmati
- Validazione messaggi tramite trust anchors
- Gestione Certificate Trust List (CTL)
Metodi Principali:
# Inizializzazione
itss = ITSStation(
its_id="VEHICLE_001",
base_dir="./pki_data/itss/"
)
# Richiesta EC
ec_response = itss.request_enrollment_certificate(
ea_url="http://localhost:5000"
)
# Richiesta AT
at_response = itss.request_authorization_ticket(
aa_url="http://localhost:5020",
enrollment_cert=ec_bytes
)
# Firma messaggio V2X
signed_message = itss.sign_message(
payload=b"Traffic alert",
authorization_ticket=at_bytes
)
# Valida messaggio
is_valid = itss.verify_message(
signed_message=signed_msg,
trust_anchors=[root_ca_cert]
)SecureRoad-PKI espone 8 blueprint REST API production-ready con autenticazione, rate limiting e CORS.
| Blueprint | Endpoints | Descrizione |
|---|---|---|
| enrollment_bp | 3 endpoints | Gestione enrollment certificates |
| authorization_bp | 3 endpoints | Gestione authorization tickets |
| trust_list_bp | 2 endpoints | Certificate Trust Lists (CTL) |
| crl_bp | 2 endpoints | Certificate Revocation Lists (CRL) |
| rootca_bp | 2 endpoints | Gestione Root CA |
| monitoring_bp | 5 endpoints | Health, metrics, monitoring |
| management_bp | 2 endpoints | Entity management |
| stats_bp | 1 endpoint | Statistiche entità |
# POST /api/enrollment/request - Richiesta Enrollment Certificate
curl -X POST http://localhost:5000/api/enrollment/request \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"its_id": "VEHICLE_001",
"public_key_pem": "-----BEGIN PUBLIC KEY-----...",
"proof_of_possession": "signature_hex"
}'
# Risposta (200 OK)
{
"certificate": "base64_encoded_asn1_oer",
"certificate_id": "hashed_id8_hex",
"expiry": "2026-10-22T10:30:00Z",
"format": "etsi_ts_103097_asn1_oer"
}
# GET /api/enrollment/certificate/<certificate_id>
curl http://localhost:5000/api/enrollment/certificate/abc123def456
# GET /api/enrollment/crl - Download CRL
curl http://localhost:5000/api/enrollment/crl# POST /api/authorization/request - Richiesta Authorization Ticket
curl -X POST http://localhost:5020/api/authorization/request \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"its_id": "VEHICLE_001",
"enrollment_certificate": "base64_encoded_ec",
"permissions": ["traffic_info", "emergency"],
"validity_hours": 168
}'
# Risposta (200 OK)
{
"authorization_ticket": "base64_encoded_asn1_oer",
"ticket_id": "hashed_id8_hex",
"expiry": "2025-10-29T10:30:00Z",
"permissions": ["traffic_info", "emergency"]
}
# POST /api/authorization/request/butterfly - Butterfly Batch Mode
curl -X POST http://localhost:5020/api/authorization/request/butterfly \
-H "Content-Type: application/json" \
-d '{
"its_id": "VEHICLE_001",
"enrollment_certificate": "base64_encoded_ec",
"batch_size": 20,
"permissions": ["traffic_info"]
}'
# Risposta (200 OK)
{
"tickets": [
{"ticket": "base64_1", "ticket_id": "hash_1", "expiry": "..."},
{"ticket": "base64_2", "ticket_id": "hash_2", "expiry": "..."},
... // 20 tickets totali, unlinkable
],
"expansion_method": "butterfly_key_expansion"
}
# GET /api/authorization/certificate - Download AA Certificate
curl http://localhost:5020/api/authorization/certificate# POST /ctl/register - Register Trust Anchor (EA/AA Auto-Registration)
# ETSI TS 102941 § 6.1.3: EA/AA registration to TLM
curl -X POST http://localhost:5050/ctl/register \
-H "Content-Type: application/json" \
-d '{
"certificate_asn1": "base64_encoded_certificate",
"authority_type": "EA",
"subject_name": "EA_001",
"expiry_date": "2026-10-22T10:30:00Z"
}'
# Risposta (200 OK)
{
"success": true,
"message": "Trust anchor registered: EA",
"hashed_id8": "a1b2c3d4e5f67890",
"responseCode": 0
}
# GET /ctl/full - Download Full CTL
curl http://localhost:5050/ctl/full
# Risposta (200 OK)
{
"version": 1,
"timestamp": "2025-10-22T10:30:00Z",
"tlm_id": "TLM_MAIN",
"trust_anchors": [
{
"authority_type": "EA",
"authority_id": "EA_001",
"subject": "CN=EnrollmentAuthority_EA_001,O=EnrollmentAuthority_EA_001,C=IT",
"added": "2025-10-22T10:30:00Z"
}
]
}
# GET /ctl/delta - Download Delta CTL
curl http://localhost:5050/ctl/delta?since=2025-10-22T10:00:00Z
# Risposta (404 Not Found - Non ancora implementato)
{
"info": "Delta CTL not available",
"message": "Delta CTL functionality not yet implemented",
"responseCode": 8
}- L'endpoint
/ctl/registerè un'estensione pragmatica per architetture distribuite - ETSI TS 102941 Section 6.5 definisce CTL come messaggi ASN.1 OER firmati con
CtlCommand - Per deployment production, considerare implementazione completa ASN.1 CTL messages
- REST API è accettabile per testing e deployment semplificato
# GET /api/crl/full - Download Full CRL
curl http://localhost:5000/api/crl/full
# GET /api/crl/delta - Download Delta CRL
curl http://localhost:5000/api/crl/delta?since_version=10# GET /health - Health Check
curl http://localhost:5000/health
# Risposta (200 OK)
{
"status": "healthy",
"entity_type": "EA",
"entity_id": "EA_001",
"uptime_seconds": 3600,
"certificates_issued": 42
}
# GET /metrics - Prometheus Metrics
curl http://localhost:5000/metrics
# GET /api/monitoring/errors - Recent Errors
curl http://localhost:5000/api/monitoring/errors?limit=10
# GET /api/monitoring/slow - Slowest Requests
curl http://localhost:5000/api/monitoring/slow?limit=5
# GET /readiness - Kubernetes Readiness Probe
curl http://localhost:5000/readiness
# GET /liveness - Kubernetes Liveness Probe
curl http://localhost:5000/livenessTutte le API protette richiedono autenticazione tramite API Key:
# Configurazione in middleware/auth_middleware.py
headers = {
"X-API-Key": "your-secure-api-key"
}Rate Limiting:
- 100 richieste/minuto per IP (configurabile)
- 429 Too Many Requests se superato
CORS:
- Configurato per accept requests da dashboard e client autorizzati
- Metodi: GET, POST, OPTIONS
- Headers: Content-Type, X-API-Key
SecureRoad-PKI utilizza ASN.1 OER encoding secondo ETSI TS 103097 V2.1.1:
| Tipo | Formato | Extension | Standard |
|---|---|---|---|
| Root Certificate | ASN.1 OER | .asn |
ETSI TS 103097 |
| Subordinate Certificate (EA/AA) | ASN.1 OER | .asn |
ETSI TS 103097 |
| Enrollment Certificate | ASN.1 OER | .asn |
ETSI TS 103097 |
| Authorization Ticket | ASN.1 OER | .asn |
ETSI TS 103097 |
| Link Certificate | ASN.1 OER | .asn |
ETSI TS 103097 |
| CRL | ASN.1 OER | .asn |
ETSI TS 102941 |
-- ETSI TS 103097 V2.1.1
EtsiTs103097Certificate ::= SEQUENCE {
version Uint8 (3),
type CertificateType,
issuer IssuerIdentifier,
toBeSigned ToBeSignedCertificate,
signature Signature
}
ToBeSignedCertificate ::= SEQUENCE {
id CertificateId,
cracaId HashedId3,
crlSeries CrlSeries,
validityPeriod ValidityPeriod,
region GeographicRegion OPTIONAL,
assuranceLevel SubjectAssurance OPTIONAL,
appPermissions SequenceOfPsidSsp OPTIONAL,
certIssuePermissions SequenceOfPsidGroupPermissions OPTIONAL,
certRequestPermissions SequenceOfPsidGroupPermissions OPTIONAL,
canRequestRollover NULL OPTIONAL,
encryptionKey PublicEncryptionKey OPTIONAL,
verifyKeyIndicator VerificationKeyIndicator
}from protocols.certificates import (
RootCertificate,
SubordinateCertificate,
EnrollmentCertificate,
AuthorizationTicket
)
# Genera certificato Root
root_cert_asn1 = RootCertificate.generate(
private_key=root_private_key,
validity_period=timedelta(days=3650)
)
# Decodifica certificato
cert_obj = RootCertificate.decode(root_cert_asn1)
print(f"Certificate ID: {cert_obj.certificate_id}")
print(f"Valid until: {cert_obj.expiry_time}")
# Verifica firma
is_valid = RootCertificate.verify_signature(
certificate_asn1=cert_bytes,
issuer_public_key=issuer_key
)SecureRoad-PKI usa HashedId8 per identificare univocamente i certificati:
from protocols.core import compute_hashed_id8
# Calcola HashedId8 da certificato
hashed_id8 = compute_hashed_id8(certificate_asn1_bytes)
print(f"Certificate ID: {hashed_id8.hex()}") # 16 hex chars (8 bytes)from entities.root_ca import RootCA
from entities.enrollment_authority import EnrollmentAuthority
from entities.authorization_authority import AuthorizationAuthority
from managers.trust_list_manager import TrustListManager
# 1. Inizializza Root CA
root_ca = RootCA() # usa config.PKI_PATHS.ROOT_CA automaticamente
print(f"✅ Root CA inizializzata: {root_ca.ca_id}")
# 2. Inizializza Trust List Manager
tlm = TrustListManager(
root_ca=root_ca,
tlm_id="TLM_MAIN",
crl_manager=root_ca.crl_manager
)
print(f"✅ TLM inizializzato: {tlm.tlm_id}")
# 3. Inizializza Enrollment Authority
ea = EnrollmentAuthority(
root_ca=root_ca,
ea_id="EA_HIGHWAY",
tlm=tlm # auto-registration
)
print(f"✅ EA inizializzata: {ea.ea_id}")
# 4. Inizializza Authorization Authority
aa = AuthorizationAuthority(
root_ca=root_ca,
tlm=tlm,
crl_manager=root_ca.crl_manager,
aa_id="AA_TRAFFIC"
)
print(f"✅ AA inizializzata: {aa.aa_id}")
# 5. Pubblica Full CTL
tlm.publish_full_ctl()
print("✅ Full CTL pubblicata")from entities.its_station import ITSStation
import requests
# 1. Inizializza ITS Station (veicolo)
vehicle = ITSStation(its_id="VEHICLE_001")
print(f"✅ Vehicle inizializzato: {vehicle.its_id}")
# 2. Richiedi Enrollment Certificate
ec_response = requests.post(
"http://localhost:5000/api/enrollment/request",
json={
"its_id": vehicle.its_id,
"public_key_pem": vehicle.get_public_key_pem()
}
)
ec_data = ec_response.json()
ec_asn1 = base64.b64decode(ec_data["certificate"])
print(f"✅ EC ottenuto: {ec_data['certificate_id']}")
# 3. Richiedi Authorization Ticket
at_response = requests.post(
"http://localhost:5020/api/authorization/request",
json={
"its_id": vehicle.its_id,
"enrollment_certificate": base64.b64encode(ec_asn1).decode(),
"permissions": ["traffic_info", "emergency"],
"validity_hours": 168 # 1 settimana
}
)
at_data = at_response.json()
at_asn1 = base64.b64decode(at_data["authorization_ticket"])
print(f"✅ AT ottenuto: {at_data['ticket_id']}")
# 4. Firma messaggio V2X
signed_message = vehicle.sign_message(
payload=b"Traffic alert: accident at km 45",
authorization_ticket=at_asn1
)
print(f"✅ Messaggio firmato: {len(signed_message)} bytes")import requests
import base64
# Richiedi batch di 20 AT (privacy-preserving)
response = requests.post(
"http://localhost:5020/api/authorization/request/butterfly",
json={
"its_id": "VEHICLE_001",
"enrollment_certificate": base64.b64encode(ec_asn1).decode(),
"batch_size": 20,
"permissions": ["traffic_info"]
}
)
tickets_data = response.json()
print(f"✅ {len(tickets_data['tickets'])} AT generati (unlinkable)")
# Usa tickets diversi per ogni messaggio (privacy)
for i, ticket_info in enumerate(tickets_data["tickets"]):
ticket_asn1 = base64.b64decode(ticket_info["ticket"])
# Usa ticket_asn1 per firmare un messaggio
print(f" Ticket {i+1}: {ticket_info['ticket_id']}")from managers.crl_manager import CRLReason
# Revoca Enrollment Certificate
ea.revoke_certificate(
certificate_id="abc123def456", # HashedId8 hex
reason=CRLReason.KEY_COMPROMISE
)
print("✅ EC revocato")
# Revoca Authorization Ticket
aa.revoke_authorization_ticket(
ticket_id="789ghi012jkl",
reason=CRLReason.CESSATION_OF_OPERATION
)
print("✅ AT revocato")
# Pubblica CRL
ea.crl_manager.publish_full_crl()
print("✅ CRL pubblicata")
# Verifica revoca
is_revoked = ea.crl_manager.is_certificate_revoked("abc123def456")
print(f"Certificato revocato: {is_revoked}")from protocols.core.crypto import verify_asn1_certificate_signature
# 1. Scarica Full CTL
ctl_response = requests.get("http://localhost:5050/api/trust_list/full")
ctl_data = ctl_response.json()
print(f"✅ CTL scaricata: version {ctl_data['version']}")
# 2. Verifica firma certificato EA
is_valid = verify_asn1_certificate_signature(
certificate_asn1=ea_cert_bytes,
issuer_public_key=root_ca.get_public_key()
)
print(f"EA certificate valido: {is_valid}")
# 3. Verifica se EA è trusted
is_trusted = tlm.is_trusted(certificate_asn1=ea_cert_bytes)
print(f"EA è trusted: {is_trusted}")
# 4. Verifica catena completa: Root -> EA -> EC
# (implementato in services/ec_validator.py)
from services.ec_validator import ECValidator
validator = ECValidator(tlm=tlm, crl_manager=ea.crl_manager)
validation_result = validator.validate_enrollment_certificate(
ec_asn1=ec_bytes
)
print(f"EC valido: {validation_result['valid']}")
print(f"Trust chain: {validation_result['trust_chain']}")SecureRoad-PKI include una suite completa di test automatici:
tests/
├── unit/ # Test unitari (componenti singoli)
│ ├── test_root_ca.py
│ ├── test_enrollment_authority.py
│ ├── test_authorization_authority.py
│ ├── test_trust_list_manager.py
│ ├── test_crl_manager.py
│ └── test_protocols.py
├── integration/ # Test integrazione (flussi E2E)
│ ├── test_enrollment_flow.py
│ ├── test_authorization_flow.py
│ ├── test_butterfly_expansion.py
│ ├── test_api_e2e_validation.py
│ └── test_revocation_flow.py
├── api/ # Test REST API
│ ├── test_enrollment_api.py
│ ├── test_authorization_api.py
│ ├── test_trust_list_api.py
│ └── test_monitoring_api.py
└── performance/ # Test performance
├── test_certificate_generation.py
└── test_concurrent_requests.py
# Tutti i test
pytest tests/ -v
# Test unitari
pytest tests/unit/ -v
# Test integrazione
pytest tests/integration/ -v
# Test API
pytest tests/api/ -v
# Test con coverage
pytest tests/ --cov=. --cov-report=html
# Test specifico
pytest tests/unit/test_root_ca.py -v
# Test con log dettagliati
pytest tests/ -v -s --log-cli-level=DEBUG# Genera report coverage HTML
pytest tests/ --cov=. --cov-report=html
# Apri nel browser
start htmlcov/index.html # Windows
open htmlcov/index.html # Mac
xdg-open htmlcov/index.html # LinuxTarget Coverage:
- Core entities: >95% (RootCA, EA, AA, TLM, ITS-S)
- Protocols layer: >90% (ASN.1 encoding/decoding)
- Managers: >90% (CRLManager, TrustListManager)
- API blueprints: >85%
- Overall: ~92%
# Esegui tester interattivo (avvia entità automaticamente)
python examples/interactive_pki_tester.py
# Menu interattivo:
# 1. Setup PKI Infrastructure
# 2. Enroll Vehicle
# 3. Request Authorization Ticket
# 4. Send V2X Message
# 5. Revoke Certificate
# 6. Verify Trust Chain
# 7. Test Butterfly Expansion
# 8. ExitDocumentazione completa e organizzata in docs/:
| Documento | Descrizione | Per cosa usarlo |
|---|---|---|
| 00_INDEX.md | Indice documentazione e quick start | Punto di partenza, navigazione docs |
| 01_ARCHITECTURE.md | Architettura sistema, layer, entità, relazioni | Capire struttura progetto, dependencies |
| 02_ENTITIES_API.md | API classi entità (metodi, parametri, returns) | Reference per usare RootCA, EA, AA, TLM, ITS-S |
| 03_DATA_STRUCTURES.md | Path management, formati file, strutture dati | Gestione path, certificate formats, metadata |
| 04_REST_API.md | Endpoint REST, blueprints, middleware | Integrare API, aggiungere endpoint |
| 05_PROTOCOLS.md | ASN.1 OER encoding, ETSI compliance, crypto | Lavorare con certificati, protocol layer |
| 06_TESTING.md | Test structure, pattern, coverage, esempi | Scrivere test, verificare coverage |
| 07_DEPLOYMENT.md | Setup, configurazione, troubleshooting | Deploy production, risolvere problemi |
Modificare entità esistente → 02_ENTITIES_API.md
Aggiungere endpoint API → 04_REST_API.md
Debugging certificati → 03_DATA_STRUCTURES.md + 05_PROTOCOLS.md
Cambiare path/config → 03_DATA_STRUCTURES.md (Path Management)
Aggiungere test → 06_TESTING.md
Problemi deployment → 07_DEPLOYMENT.md (Troubleshooting)
Il progetto segue principi SOLID e design patterns:
- Dependency Injection: Tutte le dipendenze via constructor
- Service Layer: Business logic separata da entities
- Single Responsibility: Una classe = una responsabilità
- DRY: Utilities condivise (PathManager, PKIFileHandler)
- Factory Pattern: Blueprint creation con factory functions
| Standard | Versione | Componente | Status |
|---|---|---|---|
| ETSI TS 102941 | V2.1.1 | Trust and Privacy Management | ✅ Complete |
| ETSI TS 103097 | V2.1.1 | Certificate Formats | ✅ Complete |
| IEEE 1609.2 | 2016 | Security Services | ✅ Complete |
| ETSI TS 103 831 | V1.1.1 | Trust List Management | ✅ Complete |
- Dependency Injection: Tutte le entità ricevono dipendenze via constructor
- Service Layer: Business logic separata da entities (ECValidator, AAKeyManager, ATScheduler)
- Single Responsibility: Ogni classe ha una sola responsabilità
- DRY (Don't Repeat Yourself): PathManager, PKIFileHandler, utilities condivise
- Strategy Pattern: Validazione e firma tramite interfacce
- Factory Pattern: PKIEntityManager per creazione entità
┌─────────────────────────────────────────┐
│ REST API Layer │ ← Flask blueprints, middleware
├─────────────────────────────────────────┤
│ Business Logic Layer │ ← Services (validation, scheduling)
├─────────────────────────────────────────┤
│ Entity Layer │ ← RootCA, EA, AA, TLM, ITS-S
├─────────────────────────────────────────┤
│ Protocol Layer │ ← ASN.1 encoding/decoding
├─────────────────────────────────────────┤
│ Cryptography Layer │ ← ECDSA, SHA-256, key management
└─────────────────────────────────────────┘
La configurazione è centralizzata in config/pki_config.py:
from config.pki_config import PKI_PATHS
# Percorsi automatici
print(f"Root CA dir: {PKI_PATHS.ROOT_CA}")
print(f"EA base dir: {PKI_PATHS.EA}")
print(f"AA base dir: {PKI_PATHS.AA}")
print(f"TLM dir: {PKI_PATHS.TLM_MAIN}")
# Get path specifico EA/AA
ea_path = PKI_PATHS.get_ea_path("EA_001")
aa_path = PKI_PATHS.get_aa_path("AA_001")# Port ranges (opzionale, usa default se non specificato)
export PKI_EA_PORT_START=5000
export PKI_EA_PORT_END=5019
export PKI_AA_PORT_START=5020
export PKI_AA_PORT_END=5039
export PKI_ROOT_CA_PORT=5999
export PKI_TLM_PORT=5050
# Log level
export PKI_LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR
# API Keys
export PKI_API_KEY=your-secure-api-key
# Rate limiting
export PKI_RATE_LIMIT=100 # requests per minuteLe configurazioni entità sono salvate in entity_configs.json:
{
"entities": [
{
"id": "EA_001",
"type": "EA",
"port": 5000,
"pid": 12345,
"status": "running",
"started_at": "2025-10-22T10:30:00Z"
},
{
"id": "AA_001",
"type": "AA",
"port": 5020,
"pid": 12346,
"status": "running",
"started_at": "2025-10-22T10:30:15Z"
}
]
}I contributi sono benvenuti! Per favore:
- Fork il repository
- Crea un branch per la feature (
git checkout -b feature/AmazingFeature) - Commit le modifiche (
git commit -m 'Add some AmazingFeature') - Push al branch (
git push origin feature/AmazingFeature) - Apri una Pull Request
- Segui PEP 8 per style code Python
- Aggiungi test per nuove feature
- Aggiorna documentazione se necessario
- Mantieni coverage test >85%
Questo progetto è rilasciato sotto licenza MIT. Vedi LICENSE per dettagli.
Mattia Ilmago
- GitHub: @Mattyilmago
- Repository: SecureRoads_PKI
- ETSI: Per gli standard completi e ben documentati
- IEEE 1609.2: Per le specifiche security services
- Cryptography.io: Per la libreria cryptography Python
- Flask: Per il framework web robusto
Per domande, bug report o feature request:
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
- 📧 Email: Vedi profilo GitHub per contatti
- ✅ Root CA: 100% - Self-signed cert, subordinate signing, CRL management
- ✅ Enrollment Authority: 100% - EC issuance, ETSI messages, CRL publishing
- ✅ Authorization Authority: 100% - AT issuance, Butterfly expansion, validation
- ✅ Trust List Manager: 100% - CTL management, link certificates, trust validation
- ✅ ITS Station: 95% - EC/AT requests, message signing, trust anchors
- ✅ ASN.1 OER Encoding: 100% - Full ETSI TS 103097 compliance
- ✅ REST API: 95% - 8 blueprints, auth, rate limiting
- ✅ Testing: 92% - 130+ test automatici
- ✅ Documentation: 90% - Comprehensive docs in
docs/
- HTTPS/TLS: Certificate-based authentication per API (mTLS)
- Distributed PKI: Multi-region deployment con sincronizzazione
- Performance Optimization: Caching certificati, async processing
- Monitoring Dashboard: Real-time metrics e alerting avanzato
- Docker Support: Containerizzazione per deployment semplificato
- Kubernetes: Helm charts per orchestrazione
- HSM Integration: Hardware Security Module per chiavi root
Made with ❤️ for Intelligent Transportation Systems "permissions": ["traffic_info"] }, headers={"X-API-Key": API_KEY} )
tickets = butterfly_response.json()["tickets"] print(f"✅ {len(tickets)} Authorization Tickets generati (unlinkable)")
### Esempio 2: Fleet V2X Management
```python
from entities.root_ca import RootCA
from entities.enrollment_authority import EnrollmentAuthority
from entities.authorization_authority import AuthorizationAuthority
from entities.its_station import ITSStation
# Setup PKI Infrastructure (usa percorsi da config automaticamente)
root_ca = RootCA()
ea = EnrollmentAuthority(root_ca=root_ca, ea_id="EA_HIGHWAY")
# Nota: AA richiede anche tlm e crl_manager - vedi esempi completi
aa = AuthorizationAuthority(
root_ca=root_ca,
tlm=tlm, # TrustListManager instance
crl_manager=root_ca.crl_manager,
aa_id="AA_TRAFFIC"
)
# Enroll fleet di 3 veicoli
vehicles = []
for i in range(1, 4):
vehicle = ITSStation(f"Vehicle_{i:03d}")
vehicle.generate_ecc_keypair()
# Enrollment Certificate
ec = vehicle.request_ec(ea)
# Authorization Ticket
at = vehicle.request_at(aa)
vehicles.append(vehicle)
print(f"✅ {vehicle.vehicle_id}: EC + AT ottenuti")
# Comunicazione V2X
vehicles[0].send_signed_message(
message="Traffic jam ahead!",
recipient_id="BROADCAST",
message_type="DENM"
)
print("✅ Messaggio V2X inviato e firmato")
# Revoca certificato compromesso
root_ca.revoke_certificate(compromised_cert, reason="key_compromise")
root_ca.crl_manager.publish_delta_crl()
# Verifica revoca via API
response = requests.get(f"{EA_URL}/api/crl/delta")
delta_crl = response.json()
# Controlla se un certificato è revocato
is_revoked = any(
e["serial_number"] == cert.serial_number
for e in delta_crl["revoked_certificates"]
)
print(f"Certificato revocato: {is_revoked}")# ====================
# OPZIONE 1: API ETSI Conforme (Produzione)
# ====================
from protocols.etsi_message_encoder import ETSIMessageEncoder
EA_URL = "http://localhost:5000"
encoder = ETSIMessageEncoder()
oer_request = encoder.encode_enrollment_request(
its_id="VEHICLE_001",
public_key=vehicle_pubkey,
ea_certificate=ea_cert
)
response = requests.post(
f"{EA_URL}/api/enrollment/request",
data=oer_request,
headers={
"Content-Type": "application/octet-stream",
"X-API-Key": "your-api-key"
}
)
# Decodifica risposta ASN.1 OER
enrollment_response = encoder.decode_enrollment_response(response.content)
print(f"✅ EC ricevuto: {enrollment_response['certificate']}")
# ====================
# OPZIONE 2: API Simple (Solo Testing/Debug)
# ====================
# ⚠️ NON conforme ETSI - Usa JSON per testing manuale
response = requests.post(
f"{EA_URL}/api/enrollment/request/simple",
json={
"its_id": "VEHICLE_001",
"public_key": vehicle_public_key_pem
},
headers={"X-API-Key": "your-api-key"}
)
enrollment_cert = response.json()
print(f"✅ EC ricevuto: {enrollment_cert['certificate_pem']}")# Authorization Ticket Request
AA_URL = "http://localhost:5020"
response = requests.post(
f"{AA_URL}/api/authorization/request",
json={
"vehicle_id": "Vehicle_001",
"enrollment_certificate": ec_pem,
"permissions": ["traffic_info", "emergency"]
},
headers={"X-API-Key": "your-api-key"}
)
auth_ticket = response.json()
print(f"✅ AT ricevuto: {auth_ticket['ticket_id']}")
# Butterfly Batch Request (20 tickets per privacy)
butterfly_response = requests.post(
f"{AA_URL}/api/authorization/request/butterfly",
json={
"vehicle_id": "Vehicle_001",
"enrollment_certificate": ec_pem,
"num_tickets": 20,
"permissions": ["traffic_info"]
},
headers={"X-API-Key": "your-api-key"}
)
tickets = butterfly_response.json()["tickets"]
print(f"✅ {len(tickets)} AT ricevuti (unlinkable)")SecureRoad-PKI/
├── entities/ # Entità PKI (RootCA, EA, AA, ITS-S)
├── managers/ # CRL/CTL Management
├── protocols/ # ETSI messaging, Butterfly expansion
├── api/ # REST API + middleware
│ ├── blueprints/ # Blueprint per ogni endpoint
│ ├── middleware/ # Auth, rate limiting, mTLS
│ └── flask_app_factory.py
├── utils/ # Certificati, logging, metriche
├── pki_data/ # Certificati PKI ETSI (EC, AT, Root)
├── tls_data/ # Certificati TLS per HTTPS/mTLS
├── tests/ # 130 test automatici
├── examples/ # Script dimostrativi e tester
├── scripts/ # Script gestione (start, stop, check)
├── docs/ # Documentazione dettagliata
├── server.py # Launcher server produzione + generatore entità
├── start_dashboard.ps1 # Avvio dashboard + RootCA + TLM
└── pki_dashboard.html # Dashboard web interattiva
SecureRoad-PKI utilizza due directory separate per gestire i certificati:
Certificati conformi ETSI TS 102941 e IEEE 1609.2 per firmare messaggi V2X:
pki_data/
├── root_ca/ # Root Certificate Authority
│ ├── certificates/ # Certificato Root CA
│ ├── private_keys/ # Chiave privata Root CA
│ ├── crl/ # Certificate Revocation Lists
│ ├── subordinates/ # Certificati EA/AA firmati
│ └── logs/ # Log operazioni
│
├── ea/ # Enrollment Authorities (max 20)
│ ├── EA_001/
│ │ ├── certificates/ # Certificato EA
│ │ ├── private_keys/ # Chiave privata EA
│ │ ├── enrollment_certificates/ # EC emessi
│ │ ├── crl/ # CRL specifiche
│ │ └── logs/ # Log operazioni
│ └── ... # Fino a EA_020
│
├── aa/ # Authorization Authorities (max 20)
│ ├── AA_001/
│ │ ├── certificates/ # Certificato AA
│ │ ├── private_keys/ # Chiave privata AA
│ │ ├── authorization_tickets/ # AT emessi
│ │ ├── butterfly_keys/ # Chiavi Butterfly
│ │ ├── crl/ # CRL specifiche
│ │ └── logs/ # Log operazioni
│ └── ... # Fino a AA_020
│
└── tlm/ # Trust List Manager
└── TLM_MAIN/
├── trust_lists/ # Certificate Trust Lists
├── delta_lists/ # Delta CTL
└── logs/ # Log operazioni
Certificati X.509 RFC 5280 per comunicazione sicura HTTPS tra entità PKI:
tls_data/
├── ca/ # TLS Certificate Authority
│ ├── tls_ca_cert.pem # CA Certificate
│ └── tls_ca_key.pem # CA Private Key
│
├── servers/ # Certificati server
│ ├── root_ca/
│ │ ├── rootca_cert.pem
│ │ └── rootca_key.pem
│ ├── ea/
│ │ ├── ea_001_cert.pem
│ │ ├── ea_001_key.pem
│ │ └── ... # Fino a ea_020
│ ├── aa/
│ │ ├── aa_001_cert.pem
│ │ ├── aa_001_key.pem
│ │ └── ... # Fino a aa_020
│ └── tlm/
│ ├── tlm_main_cert.pem
│ └── tlm_main_key.pem
│
└── clients/ # Certificati client (ITS-S test)
├── its_001_cert.pem
├── its_001_key.pem
└── ...
Differenze tra i due tipi di certificati:
| Aspetto | pki_data/ | tls_data/ |
|---|---|---|
| Standard | ETSI TS 102941, IEEE 1609.2 | RFC 5280 (X.509) |
| Scopo | Firmare certificati V2X (EC, AT) | Comunicazione HTTPS/mTLS |
| Utilizzato da | RootCA → EA, EA → ITS-S, AA → ITS-S | Flask server (inter-authority) |
| Formato | ASN.1 OER/DER (custom V2X) | PEM (standard TLS) |
| Validazione | ETSI signature schemes | TLS 1.2+ chain validation |
SecureRoad-PKI utilizza mTLS (mutual TLS) per la comunicazione sicura tra entità PKI.
Lo script setup_tls_certificates.py genera automaticamente:
- CA TLS: Authority per firmare certificati server/client
- Certificati Server: Per EA, AA, RootCA, TLM
- Certificati Client: Per ITS-S e testing
# Genera tutti i certificati TLS necessari
python scripts/setup_tls_certificates.pyOutput:
tls_data/
├── ca/
│ ├── tls_ca_cert.pem # ✅ Committed (CA pubblico)
│ └── tls_ca_key.pem # ⚠️ .gitignored (CA privato)
├── servers/
│ ├── root_ca/rootca_*.pem
│ ├── ea/ea_001_*.pem, ea_002_*.pem, ...
│ ├── aa/aa_001_*.pem, aa_002_*.pem, ...
│ └── tlm/tlm_main_*.pem
└── clients/
└── test_client_*.pem
{
"tls_config": {
"tls_enabled": true,
"ca_cert": "tls_data/ca/tls_ca_cert.pem",
"RootCA": {
"cert": "tls_data/servers/root_ca/rootca_cert.pem",
"key": "tls_data/servers/root_ca/rootca_key.pem"
},
"EA": {
"cert": "tls_data/servers/ea/ea_{id}_cert.pem",
"key": "tls_data/servers/ea/ea_{id}_key.pem"
},
"AA": {
"cert": "tls_data/servers/aa/aa_{id}_cert.pem",
"key": "tls_data/servers/aa/aa_{id}_key.pem"
},
"TLM": {
"cert": "tls_data/servers/tlm/tlm_main_cert.pem",
"key": "tls_data/servers/tlm/tlm_main_key.pem"
}
}
}EA_001 → 001 → ea_001_cert.pem)
# Con mTLS (HTTPS + autenticazione client)
python examples/interactive_pki_tester.py --mtls
# Senza mTLS (HTTP)
python examples/interactive_pki_tester.pyDocumentazione completa mTLS:
- docs/MTLS_SETUP.md - Setup dettagliato
- docs/MTLS_IMPLEMENTATION_SUMMARY.md - Riepilogo tecnico
- QUICK_MTLS_SETUP.md - Quick start
| Entità | Range Porte | Max Istanze | Descrizione |
|---|---|---|---|
| RootCA | 5999 | 1 | Trust anchor centrale |
| EA | 5000-5019 | 20 | Enrollment Authorities |
| AA | 5020-5039 | 20 | Authorization Authorities |
| TLM | 5050 | 1 | Trust List Manager |
| Dashboard | 8080 | 1 | Web interface |
Vantaggi:
- ✅ Zero conflitti di porta
- ✅ Scaling automatico fino a 20 EA + 20 AA
- ✅ Setup semplificato
- ✅ Compatibile con dashboard
| Endpoint | Metodo | Entità | Descrizione | Conformità ETSI | Auth |
|---|---|---|---|---|---|
/health |
GET | Tutte | Health check | - | Nessuna |
/api/docs |
GET | Tutte | Swagger UI | - | Nessuna |
/api/enrollment/request |
POST | EA | Richiesta EC | ✅ ASN.1 OER | API Key |
/api/enrollment/request/simple |
POST | EA | Richiesta EC (JSON) | API Key | |
/api/enrollment/validation |
POST | EA | Validazione EC (AA→EA) | ✅ ASN.1 OER | 🔒 mTLS |
/api/authorization/request |
POST | AA | Richiesta AT singolo | ✅ JSON | API Key |
/api/authorization/request/butterfly |
POST | AA | Richiesta batch 20 AT | ✅ ASN.1 OER | API Key |
/api/crl/full |
GET | EA, AA | Download Full CRL | ✅ PEM | Nessuna |
/api/crl/delta |
GET | EA, AA | Download Delta CRL | ✅ PEM | Nessuna |
/api/trust-list/full |
GET | TLM | Download Full CTL | ✅ JSON | Nessuna |
/api/trust-list/delta |
GET | TLM | Download Delta CTL | ✅ JSON | Nessuna |
Totale: 11 endpoint REST API
POST /api/enrollment/request- Richiesta EC (ETSI conforme - ASN.1 OER) ✅POST /api/enrollment/request/simple- Richiesta EC (JSON - solo testing)⚠️ POST /api/enrollment/validation- Validazione EC per AA (mTLS richiesto) 🔒GET /api/crl/full- Full CRLGET /api/crl/delta- Delta CRL
POST /api/authorization/request- Richiesta AT singoloPOST /api/authorization/request/butterfly- Batch 20 AT (privacy)GET /api/crl/full- Full CRLGET /api/crl/delta- Delta CRL
GET /api/trust-list/full- Full CTLGET /api/trust-list/delta- Delta CTL
GET /health- Health checkGET /api/docs- OpenAPI/Swagger
Note:
- ✅ Endpoint con ASN.1 OER sono conformi allo standard ETSI TS 102941
⚠️ Endpoint con JSON sono forniti solo per testing e debugging (non conformi)
Endpoint: POST /api/enrollment/request
✅ Conforme allo standard ETSI TS 102941
✅ Codifica ASN.1 OER (binaria)
✅ Crittografia end-to-end
✅ Proof of Possession (PoP)
Esempio:
from protocols.etsi_message_encoder import ETSIMessageEncoder
encoder = ETSIMessageEncoder()
oer_request = encoder.encode_enrollment_request(
its_id="VEHICLE_001",
public_key=vehicle_pubkey,
ea_certificate=ea_cert
)
response = requests.post(
"http://localhost:5000/api/enrollment/request",
data=oer_request,
headers={"Content-Type": "application/octet-stream", "X-API-Key": "key"}
)
enrollment_response = encoder.decode_enrollment_response(response.content)Endpoint: POST /api/enrollment/request/simple
📝 JSON leggibile
🛠️ Ideale per Swagger UI e debugging
Esempio:
response = requests.post(
"http://localhost:5000/api/enrollment/request/simple",
json={"its_id": "VEHICLE_001", "public_key": pubkey_pem},
headers={"X-API-Key": "key"}
)
cert = response.json()["certificate_pem"]Quando usare quale?
- 🏭 Produzione: Sempre usare
/api/enrollment/request(ETSI conforme) - 🧪 Testing manuale: Usare
/api/enrollment/request/simpleper debug rapido
Endpoint: POST /api/enrollment/validation
Scenario: L'Authorization Authority deve validare un Enrollment Certificate prima di emettere un Authorization Ticket.
Flusso ETSI TS 102941 Section 6.4.1:
┌──────────┐ ┌──────────┐ ┌──────────┐
│ ITS-S │ │ AA │ │ EA │
│ (Vehicle)│ │ │ │ │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
│ AT Request │ │
│ (con EC) │ │
├───────────────────>│ │
│ │ │
│ │ Validation Request │
│ │ (verifica EC) │
│ ├────────────────────>│
│ │ │
│ │ │ ✓ Verifica firma
│ │ │ ✓ Controlla CRL
│ │ │ ✓ Verifica scadenza
│ │ │
│ │ Validation Response │
│ │ (OK/INVALID/REVOKED)│
│ │<────────────────────┤
│ │ │
│ AT Response │ │
│ (se EC valido) │ │
│<───────────────────┤ │
│ │ │
Autenticazione: 🔒 mTLS obbligatorio - Solo AA con certificato client valido
Esempio:
# AA chiede validazione a EA
response = requests.post(
"http://localhost:5000/api/enrollment/validation",
data=oer_validation_request,
cert=("aa_cert.pem", "aa_key.pem"), # mTLS
verify="root_ca.pem",
headers={"Content-Type": "application/octet-stream"}
)API Key (Header)
headers = {"X-API-Key": "your-secret-key"}mTLS (Client Certificate)
requests.post(url, cert=("cert.pem", "key.pem"), verify="ca.pem")- 100 req/ora per IP (default, configurabile)
- Header:
X-RateLimit-Remaining,X-RateLimit-Reset
# Tutti i test (130 test automatici)
python -m pytest tests/ -v
# Test specifici per categoria
python -m pytest tests/test_pki_entities.py -v # Test entità PKI
python -m pytest tests/test_rest_api.py -v # Test API REST
python -m pytest tests/test_butterfly_*.py -v # Test Butterfly expansion
python -m pytest tests/test_etsi_*.py -v # Test conformità ETSI
# Con coverage report
python -m pytest tests/ --cov=. --cov-report=html# Menu interattivo con test completi
python examples/interactive_pki_tester.py
# Con entità già avviate
python examples/interactive_pki_tester.py --no-start
# Test rapido enrollment + authorization
python examples/quick_test.py- ✅ 130/130 test passing
- 📊 Coverage: ~90%
- ⚡ Performance: < 30s per full suite
- 🔒 Security tests: Certificati, firme, revoca
- 🌐 API tests: Tutti gli endpoint REST
- 🦋 Butterfly tests: Key expansion e privacy
La dashboard fornisce un'interfaccia web completa per gestire e monitorare la PKI.
# Avvia dashboard (include RootCA e TLM)
.\start_dashboard.ps1
# Apri nel browser
http://localhost:8080/pki_dashboard.html✅ Monitoraggio Real-time
- Stato di tutte le entità (RootCA, EA, AA, TLM)
- Health check automatico
- Statistiche operative
✅ Gestione Entità
- Creazione bulk di EA/AA con
server.py(nomi personalizzati) - Eliminazione permanente di entità singole
- Configurazione porte automatica
- Avvio/Stop entities
✅ Test API Interattivi
- Test enrollment certificates
- Test authorization tickets
- Test Butterfly expansion
- Download CRL/CTL
✅ Statistiche e Report
- Certificati emessi
- Performance metriche
- Log eventi
Crea multiple entità EA e AA con nomi personalizzati direttamente dalla riga di comando:
# Esempio: 3 EA e 2 AA con nomi personalizzati
python server.py --ea 3 --aa 2 --ea-names "EA_HIGHWAY,EA_CITY,EA_RURAL" --aa-names "AA_TOLL,AA_PARKING"
# Esempio: Solo EA senza nomi personalizzati (usa nomi automatici)
python server.py --ea 5
# Esempio: Solo AA con nomi personalizzati
python server.py --aa 3 --aa-names "AA_001,AA_002,AA_003"
# Esempio: Combinazione mista
python server.py --ea 2 --aa 4 --ea-names "EA_MAIN,EA_BACKUP"Parametri disponibili:
--ea N: Numero di Enrollment Authorities da creare (max 20)--aa N: Numero di Authorization Authorities da creare (max 20)--ea-names "NAME1,NAME2,...": Nomi personalizzati per EA (opzionale)--aa-names "NAME1,NAME2,...": Nomi personalizzati per AA (opzionale)
Funzionalità automatiche:
- ✅ Assegnazione porte automatica senza conflitti
- ✅ Nomi duplicati gestiti automaticamente (EA_001 → EA_001_2 se già esistente)
- ✅ Registrazione automatica nel TLM per EA
- ✅ Configurazione salvata in
entity_configs.json - ✅ Avvio automatico in background (opzionale)
### Controllo Porte
Verifica porte disponibili e in uso:
```powershell
# Windows
.\scripts\check_ports.ps1
# Windows (root directory)
.\stop_all.ps1
# Oppure con PowerShell Job cleanup
Get-Job | Stop-Job
Get-Job | Remove-Job- INDEX.md - Indice completo documentazione
- DEPLOYMENT.md - Guida deployment produzione
- SECURITY.md - Best practices sicurezza
- TEST_SUMMARY.md - Riepilogo test
- QUICK_START_RASPBERRY_PI.md - Deployment su Raspberry Pi
- entities/README_entities.md - Entità PKI
- protocols/README_protocols.md - Protocolli ETSI
- managers/README_managers.md - CRL/CTL Management
- utils/README_utils.md - Utility e helpers
- examples/README.md - Esempi e testing
Gli endpoint REST sono completamente documentati con OpenAPI/Swagger:
# Avvia un'entità
python server.py --entity EA --id EA_001
# Apri Swagger UI
http://localhost:5000/api/docs✅ ETSI TS 102941 - Security in V2X communications
✅ IEEE 1609.2 - Security services for applications and management messages
✅ ETSI TS 103097 - Security header and certificate format
- Chiavi: ECDSA con curva NIST P-256 (secp256r1)
- Hash: SHA-256
- Certificati: X.509 v3
- Encoding: ASN.1 OER (ETSI conforme)
- Butterfly Key Expansion: Generazione batch di 20 AT unlinkable
- Pseudonym Certificates: Authorization Tickets non collegabili
- Delta CRL: Riduzione dimensione liste revoca
- Implementazione core entities (RootCA, EA, AA, ITS-S, TLM)
- 11 endpoint REST API completi
- Butterfly key expansion per privacy
- CRL/CTL management con Delta support
- 130 test automatici
- Dashboard web interattiva
- Auto-start system con background processes
- Bulk entity generator
- Documentazione completa
- Repository GitHub: github.com/Mattyilmago/SecureRoads_PKI
- Issues: github.com/Mattyilmago/SecureRoads_PKI/issues
- Documentazione: docs/
Per domande o supporto, apri una issue su GitHub.
SecureRoad-PKI - Production-Ready PKI for Intelligent Transportation Systems 🚗🔐
Implementazione conforme ETSI TS 102941 per sistemi V2X sicuri e privacy-preserving