Aller au contenu principal

7. Gestion des certificats - Partie 3

(Suite du chapitre 7, Partie 2)

7.3.5. Rotation de clé de compte (Account Key Rollover)

Un client peut souhaiter modifier la clé publique associée à un compte, pour se remettre d'une compromission de clé ou pour atténuer proactivement les effets d'une compromission de clé non détectée.

Pour modifier la clé associée à un compte, le client envoie au serveur une requête contenant des signatures de l'ancienne et de la nouvelle clé. La signature de la nouvelle clé couvre l'URL du compte et l'ancienne clé, indiquant que le titulaire de la nouvelle clé demande la reprise du compte auprès du titulaire de l'ancienne clé. La signature de l'ancienne clé couvre cette requête et sa signature, et indique que le titulaire de l'ancienne clé accepte la demande de rotation.

Pour créer cet objet de requête, le client construit d'abord un objet keyChange décrivant le compte à mettre à jour et sa clé de compte :

account (requis, chaîne) : L'URL du compte en cours de modification. Le contenu de ce champ DOIT être la chaîne exacte fournie dans le champ d'en-tête Location en réponse à la requête newAccount qui a créé le compte.

oldKey (requis, JWK) : La représentation JWK de l'ancienne clé.

Le client encapsule ensuite l'objet keyChange dans un JWS « interne », signé avec la nouvelle clé de compte demandée. Ce JWS « interne » devient la charge utile du JWS « externe », qui est le corps de la requête ACME.

Le JWS externe DOIT satisfaire les exigences normales pour un corps de requête JWS ACME (voir section 6.2). Le JWS interne DOIT satisfaire les exigences normales, avec les différences suivantes :

  • Le JWS interne DOIT avoir un paramètre d'en-tête « jwk » contenant la clé publique de la nouvelle paire de clés.
  • Le JWS interne DOIT avoir le même paramètre d'en-tête « url » que le JWS externe.
  • Le JWS interne DOIT omettre le paramètre d'en-tête « nonce ».

Cette transaction comporte des signatures de l'ancienne et de la nouvelle clé, afin que le serveur puisse vérifier que les titulaires des deux clés acceptent le changement. Les signatures sont imbriquées pour préserver la propriété que toutes les signatures sur un message POST sont faites par une seule clé. Le JWS « interne » représente effectivement une demande du titulaire de la nouvelle clé de reprendre le compte auprès du titulaire de l'ancienne clé. Le JWS « externe » représente l'accord du titulaire actuel du compte sur cette demande.

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"
}

À la réception d'une requête keyChange, en plus de la validation JWS habituelle, le serveur DOIT effectuer les étapes suivantes :

  1. Vérifier que la requête POST appartient à un compte actuellement actif, comme décrit à la section 6.

  2. Vérifier que la charge utile du JWS est un objet JWS bien formé (le « JWS interne »).

  3. Vérifier que l'en-tête protégé JWS du JWS interne a un champ « jwk ».

  4. Vérifier que le JWS interne est validé avec la clé dans son champ « jwk ».

  5. Vérifier que la charge utile du JWS interne est un objet keyChange bien formé (comme décrit ci-dessus).

  6. Vérifier que les paramètres « url » des JWS interne et externe sont identiques.

  7. Vérifier que le champ « account » de l'objet keyChange contient l'URL du compte correspondant à l'ancienne clé (c'est-à-dire le champ « kid » dans le JWS externe).

  8. Vérifier que le champ « oldKey » de l'objet keyChange est identique à la clé de compte du compte en question.

  9. Vérifier qu'il n'existe pas de compte dont la clé de compte est identique à la clé dans le paramètre d'en-tête « jwk » du JWS interne.

Si toutes ces vérifications réussissent, le serveur met à jour le compte correspondant en remplaçant l'ancienne clé de compte par la nouvelle clé publique et retourne le code de statut 200 (OK). Sinon, le serveur répond avec un code de statut d'erreur et un document de problème décrivant l'erreur. S'il existe un compte existant avec la nouvelle clé fournie, le serveur DEVRAIT utiliser le code de statut 409 (Conflict) et fournir l'URL de ce compte dans le champ d'en-tête Location.

Notez que la modification de la clé de compte d'un compte NE DEVRAIT PAS avoir d'autres effets sur le compte. Par exemple, le serveur NE DOIT PAS invalider les transactions de commande ou d'autorisation en attente en raison d'un changement de clé de compte.

7.3.6. Désactivation de compte (Account Deactivation)

Un client peut désactiver un compte en publiant une mise à jour signée avec un champ de statut « deactivated » à l'URL du compte. Un client peut souhaiter le faire lorsque la clé du compte a été compromise ou lorsque le compte est mis hors service. Un compte désactivé ne peut plus demander la délivrance de certificats ni accéder aux ressources associées au compte, telles que les commandes ou les autorisations. Si le serveur reçoit un POST ou un POST-as-GET d'un compte désactivé, il DOIT retourner le code de statut 401 (Unauthorized) et une réponse d'erreur de type « urn:ietf:params:acme:error:unauthorized ».

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"
}

Le serveur DOIT vérifier que la requête est signée par la clé du compte. Si le serveur accepte la demande de désactivation, il répond avec le code de statut 200 (OK) et le contenu actuel de l'objet de compte.

Une fois qu'un compte est désactivé, le serveur NE DOIT PAS accepter d'autres requêtes autorisées par cette clé de compte. Le serveur DEVRAIT annuler toutes les opérations en attente autorisées par la clé du compte, telles que les commandes de certificats. Le serveur peut prendre diverses mesures en réponse à la désactivation d'un compte, par exemple supprimer les données associées à ce compte ou envoyer un e-mail aux contacts du compte. Le serveur NE DEVRAIT PAS révoquer les certificats délivrés pour le compte désactivé, car cela pourrait perturber le fonctionnement des serveurs utilisant ces certificats. ACME ne fournit pas de moyen de réactiver un compte désactivé.

7.4. Demande de délivrance de certificat

Un client commence le processus de délivrance de certificat en envoyant une requête POST à la ressource newOrder du serveur. Le corps du POST est un objet JWS dont la charge utile JSON est un sous-ensemble de l'objet de commande défini à la section 7.1.3, contenant les champs décrivant le certificat à délivrer :

identifiers (requis, tableau d'objets) : Tableau d'objets identifiants pour lesquels le client souhaite soumettre une commande.

  • type (requis, chaîne) : Le type de l'identifiant.

  • value (requis, chaîne) : L'identifiant lui-même.

notBefore (optionnel, chaîne) : Valeur demandée pour le champ notBefore du certificat, au format de date défini dans [RFC3339].

notAfter (optionnel, chaîne) : Valeur demandée pour le champ notAfter du certificat, au format de date défini dans [RFC3339].

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"
}

Si le serveur ne peut pas traiter la requête telle que spécifiée, il DOIT retourner une erreur et NE DOIT PAS délivrer un certificat dont le contenu diffère de celui demandé. Si le serveur exige que la requête soit modifiée d'une certaine façon, il devrait utiliser un type d'erreur et une description appropriés pour indiquer les modifications requises.

Si le serveur est prêt à délivrer le certificat demandé, il répond avec une réponse 201 (Created). Le corps de cette réponse est un objet de commande reflétant la requête du client et les autorisations que le client doit accomplir avant que le certificat puisse être délivré.

(Suite des sections 7.4.1 à 7.6...)