# Dummy CA - API Dokumentation Diese Dokumentation beschreibt die REST-API für die externe Anbindung an die Dummy CA. **Base URL:** `http://localhost:8088` (oder die entsprechende Server-Adresse) --- ## Endpunkte ### 1. Health Check Prüft, ob der Server erreichbar ist. **Endpoint:** `GET /health` **Response:** ```json { "status": "ok" } ``` **Status Codes:** - `200 OK` - Server ist erreichbar --- ### 2. CSR einreichen und signieren Reicht einen Certificate Signing Request (CSR) ein und lässt ihn signieren. **Endpoint:** `POST /csr` **Content-Type:** `application/json` **Request Body:** ```json { "csr": "BASE64_ENCODED_CSR_PEM", "action": "sign", "validity_days": 365 } ``` **Parameter:** - `csr` (string, erforderlich): Der CSR im PEM-Format, Base64-kodiert - `action` (string, erforderlich): Aktuell nur `"sign"` erlaubt - `validity_days` (integer, optional): Gültigkeitsdauer in Tagen (Standard: 365) **Response (Erfolg):** ```json { "id": "0202", "status": "success", "message": "CSR erfolgreich signiert", "certificate": "-----BEGIN CERTIFICATE-----\nMIIDXTCCAkWgAwIBAgIRAK...\n-----END CERTIFICATE-----\n" } ``` **Response (Fehler):** ```json { "error": "fehler beim Dekodieren des CSR: illegal base64 data" } ``` **Status Codes:** - `200 OK` - CSR erfolgreich signiert - `400 Bad Request` - Ungültige Anfrage (fehlende Parameter, ungültiger CSR, etc.) - `405 Method Not Allowed` - Falsche HTTP-Methode - `500 Internal Server Error` - Server-Fehler beim Signieren --- ### 3. Zertifikat abrufen Ruft ein signiertes Zertifikat anhand der Zertifikat-ID ab. **Endpoint:** `GET /certificate/{id}` **URL Parameter:** - `id` (string, erforderlich): Die Zertifikat-ID (aus der CSR-Response) **Response (Erfolg):** ```json { "id": "0202", "certificate": "-----BEGIN CERTIFICATE-----\nMIIDXTCCAkWgAwIBAgIRAK...\n-----END CERTIFICATE-----\n", "created_at": "2024-01-15T10:30:00Z" } ``` **Response (Fehler):** ``` zertifikat mit ID 0202 nicht gefunden ``` **Status Codes:** - `200 OK` - Zertifikat gefunden - `400 Bad Request` - Fehlende Zertifikat-ID - `404 Not Found` - Zertifikat nicht gefunden --- ### 4. Root-Zertifikat abrufen Ruft das Root-Zertifikat der CA ab. **Endpoint:** `GET /root` **Response:** ``` -----BEGIN CERTIFICATE----- MIIDXTCCAkWgAwIBAgIRAK... -----END CERTIFICATE----- ``` **Content-Type:** `application/x-pem-file` **Status Codes:** - `200 OK` - Root-Zertifikat erfolgreich abgerufen --- ## Beispiel-Implementierungen ### Python ```python import requests import base64 import json CA_URL = "http://localhost:8088" # 1. CSR aus Datei lesen und Base64 kodieren with open("request.csr", "rb") as f: csr_pem = f.read() csr_b64 = base64.b64encode(csr_pem).decode('utf-8') # 2. CSR einreichen response = requests.post( f"{CA_URL}/csr", json={ "csr": csr_b64, "action": "sign", "validity_days": 365 }, headers={"Content-Type": "application/json"} ) if response.status_code == 200: data = response.json() cert_id = data["id"] certificate = data["certificate"] # Zertifikat speichern with open("signed.crt", "w") as f: f.write(certificate) print(f"Zertifikat-ID: {cert_id}") else: print(f"Fehler: {response.status_code} - {response.text}") # 3. Zertifikat später abrufen cert_response = requests.get(f"{CA_URL}/certificate/{cert_id}") if cert_response.status_code == 200: cert_data = cert_response.json() print(f"Zertifikat erstellt am: {cert_data['created_at']}") ``` ### cURL ```bash # CSR einreichen CSR_B64=$(cat request.csr | base64 -w 0) curl -X POST http://localhost:8088/csr \ -H "Content-Type: application/json" \ -d "{ \"csr\": \"$CSR_B64\", \"action\": \"sign\", \"validity_days\": 365 }" # Zertifikat abrufen curl http://localhost:8088/certificate/0202 # Root-Zertifikat abrufen curl http://localhost:8088/root > root.crt ``` ### JavaScript/Node.js ```javascript const axios = require('axios'); const fs = require('fs'); const CA_URL = 'http://localhost:8088'; async function submitCSR(csrPath) { // CSR lesen und Base64 kodieren const csrPEM = fs.readFileSync(csrPath, 'utf8'); const csrB64 = Buffer.from(csrPEM).toString('base64'); try { // CSR einreichen const response = await axios.post(`${CA_URL}/csr`, { csr: csrB64, action: 'sign', validity_days: 365 }); const { id, certificate } = response.data; // Zertifikat speichern fs.writeFileSync('signed.crt', certificate); console.log(`Zertifikat-ID: ${id}`); return id; } catch (error) { console.error('Fehler:', error.response?.data || error.message); throw error; } } async function getCertificate(certId) { try { const response = await axios.get(`${CA_URL}/certificate/${certId}`); return response.data; } catch (error) { console.error('Fehler:', error.response?.data || error.message); throw error; } } // Verwendung submitCSR('request.csr') .then(certId => getCertificate(certId)) .then(data => console.log('Zertifikat erstellt:', data.created_at)) .catch(console.error); ``` ### Go ```go package main import ( "bytes" "encoding/base64" "encoding/json" "fmt" "io/ioutil" "net/http" ) const CA_URL = "http://localhost:8088" type CSRRequest struct { CSR string `json:"csr"` Action string `json:"action"` ValidityDays int `json:"validity_days"` } type CSRResponse struct { ID string `json:"id"` Status string `json:"status"` Message string `json:"message"` Certificate string `json:"certificate"` } func submitCSR(csrPath string) (string, error) { // CSR lesen csrPEM, err := ioutil.ReadFile(csrPath) if err != nil { return "", err } // Base64 kodieren csrB64 := base64.StdEncoding.EncodeToString(csrPEM) // Request erstellen reqBody := CSRRequest{ CSR: csrB64, Action: "sign", ValidityDays: 365, } jsonData, _ := json.Marshal(reqBody) // HTTP Request resp, err := http.Post(CA_URL+"/csr", "application/json", bytes.NewBuffer(jsonData)) if err != nil { return "", err } defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) if resp.StatusCode != http.StatusOK { return "", fmt.Errorf("fehler: %s", string(body)) } var csrResp CSRResponse json.Unmarshal(body, &csrResp) // Zertifikat speichern ioutil.WriteFile("signed.crt", []byte(csrResp.Certificate), 0644) return csrResp.ID, nil } ``` --- ## CSR-Format Der CSR muss im PEM-Format vorliegen und Base64-kodiert übertragen werden. **Beispiel CSR (PEM):** ``` -----BEGIN CERTIFICATE REQUEST----- MIICVjCCAT4CAQAwEjEQMA4GA1UEAwwHZXhhbXBsZTEwggEiMA0GCSqGSIb3DQEB ... -----END CERTIFICATE REQUEST----- ``` **Erstellung eines CSR:** ```bash # Private Key generieren openssl genrsa -out private.key 2048 # CSR erstellen openssl req -new -key private.key -out request.csr \ -subj "/CN=example.com/O=Example Org/C=DE" ``` --- ## Fehlerbehandlung Alle Fehler werden als HTTP-Status-Codes zurückgegeben: - **400 Bad Request**: Ungültige Anfrage (fehlende/ungültige Parameter) - **404 Not Found**: Ressource nicht gefunden (z.B. Zertifikat-ID existiert nicht) - **405 Method Not Allowed**: Falsche HTTP-Methode verwendet - **500 Internal Server Error**: Server-seitiger Fehler Fehlermeldungen werden im Response-Body als Text zurückgegeben. --- ## Wichtige Hinweise 1. **Zertifikat-Speicher**: Zertifikate werden nur im Speicher gehalten und gehen nach einem Server-Neustart verloren. 2. **Keine Authentifizierung**: Die API hat aktuell keine Authentifizierung. Für Produktionsumgebungen sollte dies hinzugefügt werden. 3. **CSR-Validierung**: Die CA validiert die CSR-Signatur, aber nicht den Inhalt des CSR. 4. **Serialnummern**: Jedes Zertifikat erhält eine eindeutige, automatisch inkrementierte Serialnummer. 5. **Gültigkeitsdauer**: Standardmäßig 365 Tage, kann über `validity_days` angepasst werden. --- ## Testen der API Sie können die API mit dem bereitgestellten Beispiel-Skript testen: ```bash ./example.sh ``` Oder manuell mit cURL: ```bash # Health Check curl http://localhost:8088/health # Root-Zertifikat curl http://localhost:8088/root ```