7. Certificate Management (Zertifikatsverwaltung) - Part 3
(Fortsetzung von Kapitel 7 Part 2)
7.3.5. Account Key Rollover (Kontoschlüsselwechsel)
Ein Client möchte möglicherweise den öffentlichen Schlüssel ändern, der einem Konto zugeordnet ist, um sich von einer Schlüsselkompromittierung zu erholen oder die Auswirkungen einer unbemerkt gebliebenen Schlüsselkompromittierung proaktiv zu mindern.
Um den einem Konto zugeordneten Schlüssel zu ändern, sendet der Client eine Anforderung an den Server, die Signaturen sowohl des alten als auch des neuen Schlüssels enthält. Die Signatur des neuen Schlüssels deckt die Konto-URL und den alten Schlüssel ab und zeigt an, dass der Inhaber des neuen Schlüssels die Übernahme des Kontos vom Inhaber des alten Schlüssels anfordert. Die Signatur des alten Schlüssels deckt diese Anforderung und ihre Signatur ab und zeigt an, dass der Inhaber des alten Schlüssels der Wechselanforderung zustimmt.
Um dieses Anforderungsobjekt zu erstellen, konstruiert der Client zunächst ein keyChange-Objekt, das das zu aktualisierende Konto und seinen Kontoschlüssel beschreibt:
account (erforderlich, Zeichenkette): Die URL des Kontos, das geändert wird. Der Inhalt dieses Felds MUSS (MUST) die genaue Zeichenkette sein, die im Location-Headerfeld als Antwort auf die newAccount-Anforderung bereitgestellt wurde, die das Konto erstellt hat.
oldKey (erforderlich, JWK): Die JWK-Darstellung des alten Schlüssels.
Der Client schließt dann das keyChange-Objekt in ein „inneres" JWS ein, das mit dem angeforderten neuen Kontoschlüssel signiert ist. Dieses „innere" JWS wird zur Nutzlast des „äußeren" JWS, d. h. des Körpers der ACME-Anforderung.
Das äußere JWS MUSS (MUST) die normalen Anforderungen für ACME-JWS-Anforderungskörper erfüllen (siehe Abschnitt 6.2). Das innere JWS MUSS (MUST) die normalen Anforderungen erfüllen, mit den folgenden Unterschieden:
- Das innere JWS MUSS (MUST) einen „jwk"-Headerparameter haben, der den öffentlichen Schlüssel des neuen Schlüsselpaars enthält.
- Das innere JWS MUSS (MUST) denselben „url"-Headerparameter haben wie das äußere JWS.
- Das innere JWS MUSS (MUST) den „nonce"-Headerparameter weglassen.
Diese Transaktion hat Signaturen sowohl des alten als auch des neuen Schlüssels, damit der Server überprüfen kann, dass die Inhaber beider Schlüssel der Änderung zustimmen. Die Signaturen sind verschachtelt, um die Eigenschaft zu erhalten, dass alle Signaturen einer POST-Nachricht von einem Schlüssel signiert sind. Das „innere" JWS stellt effektiv eine Anforderung des neuen Schlüsselinhabers dar, das Konto vom alten Schlüsselinhaber zu übernehmen. Das „äußere" JWS stellt die Zustimmung des aktuellen Kontoinhabers zu dieser Anforderung dar.
POST /acme/key-change HTTP/1.1
Host: example.com
Content-Type: application/jose+json
{
"protected": base64url({
"alg": "ES256",
"kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "S9XaOcxP5McpnTcWPIhYuB",
"url": "https://example.com/acme/key-change"
}),
"payload": base64url({
"protected": base64url({
"alg": "ES256",
"jwk": /* new key */,
"url": "https://example.com/acme/key-change"
}),
"payload": base64url({
"account": "https://example.com/acme/acct/evOfKhNU60wg",
"oldKey": /* old key */
}),
"signature": "Xe8B94RD30Azj2ea...8BmZIRtcSKPSd8gU"
}),
"signature": "5TWiqIYQfIDfALQv...x9C2mg8JGPxl5bI4"
}
Beim Empfang einer keyChange-Anforderung MUSS (MUST) der Server zusätzlich zur typischen JWS-Validierung die folgenden Schritte ausführen:
-
Überprüfen, ob die POST-Anforderung zu einem aktuell aktiven Konto gehört, wie in Abschnitt 6 beschrieben.
-
Prüfen, ob die Nutzlast des JWS ein wohlgeformtes JWS-Objekt ist (das „innere JWS").
-
Prüfen, ob der JWS Protected Header des inneren JWS ein „jwk"-Feld hat.
-
Prüfen, ob das innere JWS mit dem Schlüssel in seinem „jwk"-Feld validiert wird.
-
Prüfen, ob die Nutzlast des inneren JWS ein wohlgeformtes keyChange-Objekt ist (wie oben beschrieben).
-
Prüfen, ob die „url"-Parameter des inneren und äußeren JWS identisch sind.
-
Prüfen, ob das „account"-Feld des keyChange-Objekts die URL des Kontos enthält, das dem alten Schlüssel entspricht (d. h. dem „kid"-Feld im äußeren JWS).
-
Prüfen, ob das „oldKey"-Feld des keyChange-Objekts mit dem Kontoschlüssel des betreffenden Kontos identisch ist.
-
Prüfen, ob kein Konto mit einem Kontoschlüssel existiert, der mit dem Schlüssel im „jwk"-Headerparameter des inneren JWS identisch ist.
Wenn alle diese Prüfungen bestanden werden, aktualisiert der Server das entsprechende Konto, indem er den alten Kontoschlüssel durch den neuen öffentlichen Schlüssel ersetzt, und gibt den Statuscode 200 (OK) zurück. Andernfalls antwortet der Server mit einem Fehlerstatuscode und einem Problemdokument, das den Fehler beschreibt. Wenn ein bestehendes Konto mit dem bereitgestellten neuen Schlüssel existiert, SOLLTE (SHOULD) der Server den Statuscode 409 (Conflict) verwenden und die URL dieses Kontos im Location-Headerfeld angeben.
Beachten Sie, dass die Änderung des Kontoschlüssels eines Kontos KEINE (SHOULD NOT) anderen Auswirkungen auf das Konto haben SOLLTE. Beispielsweise DARF (MUST NOT) der Server ausstehende Bestellungs- oder Autorisierungstransaktionen aufgrund einer Änderung des Kontoschlüssels nicht ungültig machen.
7.3.6. Account Deactivation (Kontodeaktivierung)
Ein Client kann ein Konto deaktivieren, indem er eine signierte Aktualisierung mit dem Statusfeld „deactivated" an die Konto-URL sendet. Ein Client möchte dies möglicherweise tun, wenn der Kontoschlüssel kompromittiert wurde oder das Konto nicht mehr benötigt wird. Ein deaktiviertes Konto kann keine Zertifikatsausstellung mehr anfordern oder auf kontobezogene Ressourcen wie Bestellungen oder Autorisierungen zugreifen. Wenn der Server eine POST- oder POST-as-GET-Anforderung von einem deaktivierten Konto erhält, MUSS (MUST) er den Statuscode 401 (Unauthorized) und eine Fehlerantwort vom Typ „urn:ietf:params:acme:error:unauthorized" zurückgeben.
POST /acme/acct/evOfKhNU60wg HTTP/1.1
Host: example.com
Content-Type: application/jose+json
{
"protected": base64url({
"alg": "ES256",
"kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "ntuJWWSic4WVNSqeUmshgg",
"url": "https://example.com/acme/acct/evOfKhNU60wg"
}),
"payload": base64url({
"status": "deactivated"
}),
"signature": "earzVLd3m5M4xJzR...bVTqn7R08AKOVf3Y"
}
Der Server MUSS (MUST) überprüfen, ob die Anforderung mit dem Kontoschlüssel signiert ist. Wenn der Server die Deaktivierungsanforderung akzeptiert, antwortet er mit dem Statuscode 200 (OK) und dem aktuellen Inhalt des Kontoobjekts.
Sobald ein Konto deaktiviert ist, DARF (MUST NOT) der Server keine weiteren Anforderungen akzeptieren, die durch diesen Kontoschlüssel autorisiert sind. Der Server SOLLTE (SHOULD) alle ausstehenden Operationen abbrechen, die durch den Kontoschlüssel autorisiert sind, wie z. B. Zertifikatsbestellungen. Der Server kann als Reaktion auf die Kontodeaktivierung verschiedene Maßnahmen ergreifen, z. B. die mit dem Konto verbundenen Daten löschen oder eine E-Mail an die Kontakte des Kontos senden. Der Server SOLLTE NICHT (SHOULD NOT) Zertifikate widerrufen, die von einem deaktivierten Konto ausgestellt wurden, da dies zu Betriebsunterbrechungen bei Servern führen kann, die diese Zertifikate verwenden. ACME bietet keine Möglichkeit, ein deaktiviertes Konto zu reaktivieren.
7.4. Applying for Certificate Issuance (Beantragung der Zertifikatsausstellung)
Ein Client beginnt den Zertifikatsausstellungsprozess, indem er eine POST-Anforderung an die newOrder-Ressource des Servers sendet. Der Körper des POST ist ein JWS-Objekt, dessen JSON-Nutzlast eine Teilmenge des in Abschnitt 7.1.3 definierten Bestellungsobjekts ist und Felder enthält, die das auszustellende Zertifikat beschreiben:
identifiers (erforderlich, Objektarray): Ein Array von Identifikatorobjekten, für die der Client eine Bestellung einreichen möchte.
-
type (erforderlich, Zeichenkette): Der Typ des Identifikators.
-
value (erforderlich, Zeichenkette): Der Identifikator selbst.
notBefore (optional, Zeichenkette): Der angeforderte Wert für das notBefore-Feld im Zertifikat, im in [RFC3339] definierten Datumsformat.
notAfter (optional, Zeichenkette): Der angeforderte Wert für das notAfter-Feld im Zertifikat, im in [RFC3339] definierten Datumsformat.
POST /acme/new-order HTTP/1.1
Host: example.com
Content-Type: application/jose+json
{
"protected": base64url({
"alg": "ES256",
"kid": "https://example.com/acme/acct/evOfKhNU60wg",
"nonce": "5XJ1L3lEkMG7tR6pA00clA",
"url": "https://example.com/acme/new-order"
}),
"payload": base64url({
"identifiers": [
{ "type": "dns", "value": "www.example.org" },
{ "type": "dns", "value": "example.org" }
],
"notBefore": "2016-01-01T00:04:00+04:00",
"notAfter": "2016-01-08T00:04:00+04:00"
}),
"signature": "H6ZXtGjTZyUnPeKn...wEA4TklBdh3e454g"
}
Wenn der Server die Anforderung nicht wie angegeben erfüllen kann, MUSS (MUST) er einen Fehler zurückgeben und DARF NICHT (MUST NOT) ein Zertifikat ausstellen, dessen Inhalt sich von dem der Anforderung unterscheidet. Wenn der Server verlangt, dass die Anforderung in irgendeiner Weise geändert wird, SOLLTE er den erforderlichen Änderungen mit einem geeigneten Fehlertyp und einer Beschreibung hinweisen.
Wenn der Server bereit ist, das angeforderte Zertifikat auszustellen, antwortet er mit einer 201 (Created)-Antwort. Der Körper dieser Antwort ist ein Bestellungsobjekt, das die Anforderung des Clients und alle Autorisierungen widerspiegelt, die der Client abschließen muss, bevor das Zertifikat ausgestellt wird.
(Fortsetzung der Abschnitte 7.4.1–7.6...)