init
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
# BSI-Konformität
|
||||
|
||||
Mapping der Vorgaben aus den BSI-Richtlinien auf die Code-Stellen in diesem
|
||||
Projekt. Quelle aller Anforderungen: **BSI TR-03129-4**, **BSI TR-03109-1**
|
||||
und **SM-PKI Certificate Policy**.
|
||||
|
||||
## 1. TR-03129-4 — Schnittstelle zur Zertifizierungsstelle
|
||||
|
||||
### 1.1 Transportsicherheit (mTLS)
|
||||
|
||||
| Anforderung | Code-Stelle |
|
||||
| ------------------------------------------------------------------ | -------------------------------------- |
|
||||
| SOAP-Nachrichten enthalten **keine** Auth-Daten. | `builders/soap_req.rs` |
|
||||
| Autorisierung + Verschlüsselung **ausschließlich** via mTLS. | `adapters/sub_ca.rs` |
|
||||
| Client-Cert (EMT-Testzertifikat) konfiguriert in `reqwest`. | `SubCaSoapAdapter::new(...)` |
|
||||
| Server-Cert der CA gegen vertrauten CA-Trust-Store verifiziert. | `SubCaSoapAdapter::new(...)` |
|
||||
|
||||
Konkret in `reqwest`:
|
||||
|
||||
```rust
|
||||
reqwest::ClientBuilder::new()
|
||||
.use_rustls_tls()
|
||||
.identity(reqwest::Identity::from_pem(client_pem_bundle)?)
|
||||
.add_root_certificate(reqwest::Certificate::from_pem(ca_pem)?)
|
||||
.build()?
|
||||
```
|
||||
|
||||
### 1.2 WSDL-Konformität
|
||||
|
||||
| Anforderung | Code-Stelle |
|
||||
| -------------------------------------------------------- | ------------------------- |
|
||||
| Envelope folgt der offiziellen BSI-WSDL. | `builders/soap_req.rs` |
|
||||
| Operation `RequestCertificate` mit korrektem Namespace. | `SoapRequestBuilder::build_request_certificate` |
|
||||
| CSR wird Base64-kodiert im Feld `certReq` übertragen. | dito |
|
||||
|
||||
Bewusste Entscheidung: **kein WSDL-Codegen**. Die Surface ist klein,
|
||||
`quick-xml` reicht; Codegen-Crates für Rust sind unausgereift und brittle.
|
||||
|
||||
### 1.3 Asynchrone Callbacks (Polling-Verbot)
|
||||
|
||||
| Anforderung | Code-Stelle |
|
||||
| ------------------------------------------------------ | -------------------------------------------------- |
|
||||
| `callbackIndicator = callback_possible` im Request. | `SoapRequestBuilder::build_request_certificate` |
|
||||
| Eindeutige `messageID` pro Anfrage. | `SoapRequestBuilder::message_id` |
|
||||
| Synchroner Response enthält i.d.R. nur `returnCode`. | `SubCaSoapAdapter::request_certificate` |
|
||||
| Webhook nimmt das fertige Zertifikat entgegen. | Axum-Handler (folgt; `POST /pki/callback`) |
|
||||
| Zuordnung Callback → Request über `messageID`. | `StoragePort::save_pending_request` / Lookup |
|
||||
| Zertifikatskette aus `certificateSeq` extrahieren. | Axum-Handler / `HandleCaCallback` |
|
||||
|
||||
**Sicherheitspunkt:** `messageID` allein ist **kein** Trust-Boundary. Der
|
||||
Callback-Handler muss zusätzlich:
|
||||
|
||||
1. mTLS-Client-Cert der CA prüfen.
|
||||
2. SOAP-Signatur der Nachricht prüfen.
|
||||
|
||||
Erst dann darf in der DB nachgeschlagen werden.
|
||||
|
||||
### 1.4 Datenfelder
|
||||
|
||||
| Feld | Inhalt | Quelle |
|
||||
| ----------------- | ------------------------------------------ | ----------------------------------- |
|
||||
| `certReq` | Base64(CSR-DER) — vom HSM erzeugt. | `HsmPort::sign_csr` |
|
||||
| `messageID` | UUIDv4, persistiert in `pending_requests`. | `SoapRequestBuilder::message_id` |
|
||||
| `callbackIndicator` | `callback_possible` | `SoapRequestBuilder` |
|
||||
| `certificateSeq` | Antwort der CA via Callback. | Axum-Handler |
|
||||
|
||||
## 2. TR-03109-1 — Initial-Konfiguration
|
||||
|
||||
### 2.1 Dateiformat `iconfig.tar`
|
||||
|
||||
| Pflicht-Inhalt | Code-Stelle |
|
||||
| ----------------------------------------------- | ------------------------------------ |
|
||||
| `iconfig.xml` — Konfiguration. | `builders/iconfig.rs` |
|
||||
| `iconfig.sig` — XML-DSig über `iconfig.xml`. | `builders/iconfig.rs` + `HsmPort` |
|
||||
| Beide Dateien in einem Tar-Archiv verpackt. | `builders/iconfig.rs` (Tar-Stufe) |
|
||||
|
||||
### 2.2 Inhalt der `iconfig.xml`
|
||||
|
||||
Pflichtbestandteile:
|
||||
|
||||
- Admin-Zertifikate (öffentliche Teile).
|
||||
- CA-Zertifikatskette.
|
||||
- Netzwerkprofil (IP-Access für WAN).
|
||||
- Kommunikationsprofil (TLS-Admin für WAN-Schnittstelle).
|
||||
|
||||
Generierung im `InitialConfigBuilder` via `quick-xml`. Eingangsdaten aus der
|
||||
Domäne (`Gateway`) bzw. aus Konfig-Files.
|
||||
|
||||
### 2.3 Kryptografische Signatur `iconfig.sig`
|
||||
|
||||
| Anforderung | Code-Stelle |
|
||||
| -------------------------------------------------------------------- | ------------------------------------ |
|
||||
| Signatur mit `GWADM_SIG_PRV` (privater Signaturschlüssel des GWA). | `HsmPort::sign_xml` |
|
||||
| Schlüssel liegt im HSM; Zugriff via PKCS#11. | `adapters/hsm.rs` (`cryptoki`) |
|
||||
| Signatur über **kanonische** Bytes (XML-C14N). | `InitialConfigBuilder` |
|
||||
|
||||
**Implementierungs-Hinweis (XML-DSig):**
|
||||
|
||||
Reines Rust für XML-DSig ist nicht reif. Optionen:
|
||||
|
||||
1. `xmlsec1` CLI über `std::process::Command` aus dem Adapter aufrufen
|
||||
(pragmatischer Start).
|
||||
2. `libxmlsec1` über FFI binden.
|
||||
3. C14N + Signatur manuell via `cryptoki` zusammensetzen (fehleranfällig
|
||||
wegen exakter Canonicalization).
|
||||
|
||||
Wir starten mit Option 1 und kapseln das vollständig hinter `HsmPort::sign_xml`,
|
||||
damit ein späterer Wechsel keinen Domänen-Code anfasst.
|
||||
|
||||
## 3. SM-PKI Certificate Policy
|
||||
|
||||
### 3.1 Schlüsselspeicherung
|
||||
|
||||
| Anforderung | Code-Stelle |
|
||||
| ------------------------------------------------------------ | ------------------------- |
|
||||
| Alle Teilnehmer-Schlüssel in HSMs ≥ "Security Level 1". | `adapters/hsm.rs` |
|
||||
| SoftHSMv2 erfüllt SL1 **nur** für Entwicklung. | siehe Sicherheitshinweis |
|
||||
|
||||
In Produktion: zertifiziertes HSM (CC EAL4+) zwingend. Der `HsmPort` bleibt
|
||||
identisch — nur das Backend tauscht.
|
||||
|
||||
### 3.2 Zertifikatslaufzeiten und Rotation
|
||||
|
||||
| Anforderung | Code-Stelle |
|
||||
| -------------------------------------------------------- | ------------------------------------------ |
|
||||
| Endentitäten/Sub-CAs in der Regel alle 2 Jahre. | Datenmodell `Certificate.not_after` |
|
||||
| Erneuerung rechtzeitig vor Ablauf (Standard: 30 Tage). | `RenewExpiringCertificates::run(days=30)` |
|
||||
| Asynchroner `RequestCertificate`-Flow. | siehe §1.3 |
|
||||
| Testbare Zeitquelle. | `ClockPort` / `SystemClock` |
|
||||
|
||||
Das 30-Tage-Fenster ist Default, kein Gesetz — über Config einstellbar.
|
||||
|
||||
## 4. Offene Punkte
|
||||
|
||||
- Konkrete Werte der BSI-Namespace-URIs und Operationsnamen aus der aktuellen
|
||||
WSDL-Version müssen in `builders/soap_req.rs` als Konstanten gepflegt
|
||||
werden, sobald die WSDL aus dem BSI-Repo gezogen ist.
|
||||
- Schema-Validierung der `iconfig.xml` gegen das BSI-XSD ist offen; sinnvoll
|
||||
als zusätzlicher Adapter-Check vor dem Signieren.
|
||||
- mTLS-Server (Axum für Callback) muss Client-Cert-Pinning auf die CA-Cert
|
||||
durchsetzen — Konfiguration unter [`development.md`](development.md).
|
||||
Reference in New Issue
Block a user