Présentation des processus cryptographiques¶


Date


sept. 21, 2023


Rédigé par


Hubert TOUVET, Vincent Cardon


S'applique à WAPT


>= 188.8.131.5280


Version du document


184.108.40.206-0


Hash Git


d837363b9ec76db8ed2b383bacd1339cdf00d4cd
Les processus cryptographiques sont utilisés dans les activités suivantes :
Signature et vérification des fichiers contenus dans un paquet.
Signature et vérification des attributs d'un paquet.
Signature et vérification des actions immédiates sur les clients WAPT.
Signature des inventaires et statut des clients WAPT.
Authentification de la connexion Websockets des clients WAPT sur le Serveur WAPT.
Communication HTTPS entre les clients WAPT et le Serveur WAPT.
Communications HTTPS entre la console WAPT et le serveur WAPT.
Communications HTTPS entre les clients WAPT et les dépôts WAPT.
<WAPT>: répertoire d'installation de WAPT. Par défaut
%Program Files (x86)%\WAPT.
<WAPT>\wapt-get.ini: fichier de configuration du client WAPT (wapt-get et waptservice).
<WAPT>\ssl: répertoire par défaut pour les certificats de confiance pour signer les paquets et les actions.
<WAPT>\ssl\server: répertoire par défaut pour stocker les certificats https du serveur WAPT (épinglage de certificat).
<WAPT>\private: répertoire par défaut pour les certificats permettant de signer l'inventaire et les connexions Websocket.
%LOCALAPPDATA%\waptconsole\waptconsole.ini: fichier de configuration de la console WAPT et des actions de développement de l'outil wapt-get.
%aAPPDATA%\waptconsole\ssl: répertoire par défaut pour les certificats de confiance pour l'import de paquets WAPT depuis un dépôt externe (c.à.d. les modèles de paquets).
Organisation
Une Organisation est le périmètre de responsabilité dans lequel est exploitée la solution WAPT.
Autorité de Certification
Administrateurs
Les Administrateurs sont en possession d'une clé RSA personnelle et d'un certificat signé par l"Autorité de Certification de l"Organisation ; ils ont aussi un identifiant et un mot de passe pour accéder à la console WAPT.
Agent WAPT
Les clients WAPT sont l'ensemble des appareils que les Administrateurs de l"Organisation peuvent gérer avec WAPT. Les clients peuvent être ou non un membre du dmaine Active Directory de l"Organisation.
Serveur WAPT
Le serveur WAPT est un serveur Linux / Nginx / PostgreSQL de l"Organisation qui gère l'inventaire et le status des Postes clients WAPT.
Par défaut, le serveur WAPT joue également le rôle de dépôt WAPT interne. Le serveur WAPT a un compte ordinateur dans l'Active Directory de l"Organisation.
Dépôts WAPT internes
Les dépôt internet WAPT sont un ou plusieurs serveur Linux / Nginx qui diffusent aux Postes clients WAPT en HTTPS des paquets WAPT signés.
Dépôts WAPT externes
Les dépôts WAPT externe sont des dépôts WAPT publics que les Développeurs de Paquets peuvent utiliser pour importer des paquets conçus par d'autres Organisations, sous condition d'en vérifier l'adéquation aux normes internes de sûreté et de sécurité ;
Serveur Active Directory
Le serveur Active Directory gérant le domaine AD de l"Organisation ;
L'Agent WAPT, le Serveur WAPT et le Console WAPT utilisent à la fois du code Python interprété et du code compilé Lazarus / FPC.
Le code Lazarus / FPC utilise le framework mORMot (>= 2.0.4383) pour la gestion du protocole https, la gestion du client kerberos, les opérations sur les certificats X509, et les opérations cryptographiques (Hash, RSA).
Le framework mORMot est lui-même configuré et lié pour utiliser la bibliothèque OpenSSL 1.1.1s 1 Nov 2022 pour les sockets TLS, les opérations RSA asymétriques (génération de clé, chiffrement, déchiffrement, signature, vérification), et les opérations de certificats X509.
Le code Python (Agent WAPT, Serveur WAPT, paquets WAPT) est lié aux mêmes bibliothèques OpenSSL 1.1.1s 1 Nov 2022 et utilise les modules suivants :
Du côté de l'Agent WAPT :
les modules python cryptographie==3.3.2 et pyOpenSSL==20.0.1 liés à openssl 1.1.1s : utilisés pour toutes les opérations cryptographiques RSA, les générations de certificats X509 et les vérifications de signatures dans l'agent WAPT en python.
winkerberos==0.8.0 (agent Windows) / kerberos==1.3.1 (agent Linux) et requests-kerberos==0.12.0 : utilisés pour authentifier le client WAPT lors de son premier enregistrement avec le Serveur WAPT.
certifi==2021.5.30 : utilisé comme base pour les certificats des Autorités Racine.
Du coté du Serveur WAPT :
Module ssl Python 3.8.16 lié à openssl 1.1.1s.
cryptography==3.3.2 et pyOpenSSL==20.0.1 liés sur openssl 1.1.1s : utilisés pour toutes les opérations cryptographiques RSA telles que les générations de clés, les générations de certificats X509 et les vérifications de signatures.
Sur le Serveur WAPT, nginx/1.18.0 est configuré pour servir les paquets par https, gérer les demandes https de l'API du Server WAPT, gérer les authentifications Kerberos des clients et la vérification des certificats des clients. Le serveur nginx est configuré pour TLS1.2, cipher "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH".
Il y a trois types de PKI / CA dans une configuration WAPT standard


Type


Utilisation


Origine et enregistrement


Renouvellement


Révocation


Certificat de transport HTTPS


L'objectif de ce certificat est de sécuriser la communication entre l'Agent WAPT et le Serveur WAPT et pour authentifier le Serveur WAPT.


Le certificat est délivré par une Autorité de certification de confiance pour l'ordinateur client (la Autorité de Certification doit être intégrée dans le Certificate Store local), et la clé privée https doit être stockée sur le serveur http nginx.


Le certificat doit être renouvelé comme tous les certificats https gérés par l"Organisation.


Le certificat doit être révoqué comme tous les certificats https gérés par l"Organisation.


Le certificat de l'Administrateur / Packager


L'objectif de ce certificat est de signer les paquets et les messages


La CRL doit être publiée via http et accessible par le serveur WAPT, et l'attribut du point de distribution de la CRL doit être défini dans le certificat. Le Serveur WAPT redistribue la CRL à l'Agent WAPT.


Le certificat du client de l'Agent WAPT


L'objectif de ce certificat est d'authentifier l'Agent WAPT auprès du serveur WAPT, de signer les données et enfin de chiffrer éventuellement les données que l'Agent WAPT envoie au Serveur WAPT. Ce certificat est purement technique pour identifier un client WAPT et est créé par un processus CSR initié par le client lors de l'enregistrement de l'Agent WAPT auprès du Serveur WAPT. La clé privée est déposée sur le client dans


Le Autorité de certification est géré en interne par le Serveur WAPT et est utilisé uniquement pour l'authentification des clients avec le Serveur WAPT.


Le renouvellement se fait lors de l'enregistrement ou bien lorsque la vérification du client échoue.


La révocation est gérée en interne par le Serveur WAPT qui configure une CRL pour le service Nginx.
Les paquets et actions de l"Administrateur sont signés pour n'autoriser que les Administrateurs de confiance à intervenir sur les postes.
L"Administrateur de la solution WAPT a en sa possession :
Une clé privée RSA de 2048 bits chiffrée par l'algorithme aes-256-cbc.
Note
Le processus d'émission de ces clés, la signature du certificat, la distribution et la révocation sont à la charge de l"Organisation utilisant WAPT et sortent donc du périmètre fonctionnel de WAPT.
Cependant, pour facilement tester la solution, WAPT propose une fonction pour générer une clé RSA et un certificat X509 :
La clé RSA générée est de 2048 bits, chiffrée par l'algorithme aes-256-cbc et encodée en format PEM avec l'extension .pem.
Le certificat est soit autosigné, soit signé par une Autorité de Confiancedont on a à disposition la clé et le certificat en format PEM.
Si le certificat est autosigné, son attribut KeyUsage comporte le flag keyCertSign.
Si l"Administrateur est habilité par l"Organisation à signer des paquets contenant du code python (présence du fichier
setup.py), l'attribut du certificat extendedKeyUsage comporte le flag CodeSigning.
Le certificat X509 est encodé et remis à l"Administrateur en format PEM avec l'extension .crt .
L'Agent WAPT fait confiance à tous les certificats X509 non expirés situés dans le répertoire <wapt>\ssl de l'agent WAPT.
Si un fichier .crt encodé en format PEM contenu dans le répertoire
<wapt>\ssl de l'Agent WAPT contient plusieurs certificats, seul le premier est reconnu.
l'agent WAPT vérifie uniquement les dates de validité (attributs
notValidBefore/
notValidAfter). Le certificat est valide si (
Now >=
notValidBefore et
Now <=
notValidAfter").
Le client WAPT (waptservice) utilise des clés RSA et un certificat X509 pour interagir avec le Serveur WAPT.
Le certificat du client WAPT est utilisé dans les situations suivantes :
Pour contrôler l'accès aux paquets hosts et aux autres dépôts de paquets lorsque l'authentification par certificat client est activée dans la configuration du serveur NGINX.
Lors de la mise à jour du statut du poste sur le serveur. (update_server_status) : signature des informations.
Lors de la connexion Websocket du poste vers le serveur (waptservice) : signature de l'UUID du poste.
A l'issu du processus d'installation de l'agent WAPT sur le Poste client, l'agent WAPT s'enregistre automatiquement auprès du serveur WAPT en émettant une requête https authentifiée par Kerberos qui utilise le TGT du compte machine.
L'agent WAPT utilise les API kerberos de Windows en s'appuyant sur les modules python kerberos-sspi et requests-kerberos .
Note
Cette procédure fonctionne si et seulement si le poste client est joint au domaine Windows pour lequel le Serveur WAPT est configuré.
Si la clé et les certificats n'ont pas encore été générés, ou s'ils ne correspondent pas au FQDN actuel de la machine, l'agent WAPT génère une clé RSA et un certificat X509 autosigné avec les paramètres suivants :
La clé est de type RSA 2048 bits encodée en PEM et stockée dans le fichier
<WAPT>\private\<device UID>.pem.
Le certificat généré a les attributs suivants :
Sujet.COMMON_NAME=
<device UID>.
Subject.ORGANIZATIONAL_UNIT_NAME=
nom de l':term:`Organisation` enregistré dans la base de registre du client Windows.
SubjectAlternativeName.DNSName = <device UID>.
BasicConstraint.CA = True.
Validity=
10 years.
Serialnumber=
random.
-
Le certificat est sauvegardé dans le fichier
<WAPT>\private\<device UID>.crt.
Note
Seul le compte machine et les Administrateurs Locaux ont accès au répertoire
<WAPT>\privatecar des ACL spécifiques sont appliquées à l'installation de l'agent WAPT sur le poste.
L'inventaire ou les mises à jour de statuts du client sont envoyés au serveur WAPT par requête HTTPS POST.
On authentifie la requête https POST en ajoutant deux headers http spécifiques :
-
X-Signature :
-
Encodage en JSON des informations BLOB d'inventaire ou de status.
-
Signature du json avec la clé privée du client WAPT : hachage sha256 et padding PKCS#1 v1.5.
-
encodage de la signature en base64.
-
X-Signer : Subject.COMMON_NAME du client WAPT.
Après avoir initialement authentifié le client WAPT avec kerberos, le Serveur WAPT reçoit la demande de signature de certificat envoyée par le client, signe un certificat client approprié et le stocke dans la table hosts de son inventaire au format PEM (colonne host_certificate).
Le certificat client nouvellement signé est envoyé au client.
Le certificat est sauvegardé dans le fichier
<WAPT>\private\<device UID>.crt.
Note
Si le poste client WAPT est renommé, la clé privée et le certificat sont recréés.
Lors de la tentative de mise à jour de status du client vers le serveur, la requête POST sera refusée, car la machine est enregistrée dans la base de données avec un autre certificat.
La machine tentera alors de se ré-enregistrer (register) avec une authentification kerberos ; ainsi le nouveau certificat sera enregistré dans la base de données.
Pour permettre des actions immédiates sur les clients WAPT, le service WAPT déployé sur les clients tente d'établir et de maintenir une connexion Websocket vers le serveur WAPT.
Cette connexion s'effectue sur un connexion chiffrée avec le protocole TLS et utilise côté client le même bundle de certificat que la connexion HTTPS Client vers Serveur WAPT.
Le paramètre
verify_cert de la section
[global] du fichier
%LOCALAPPDATA%\waptconsole\waptconsole.ini peut avoir plusieurs valeurs :
verify_cert=
Trueou
1
Cette méthode ne fonctionnera bien que si le Serveur WAPT HTTPS est configuré pour renvoyer son certificat et les certificats intermédiaires à l'initialisation de communication TLS.
verify_cert = <chemin vers fichier .pem>
Cette méthode vérifie le certificat HTTPS du serveur WAPT en utilisant le bundle de certificats indiqué. Tous les certificats de CA intermédiaires et root DOIVENT être rassemblés dans un fichier au format .pem.
verify_cert=
Falseou
0
Cette méthode ne vérifie pas le certificat HTTPS du serveur WAPT.
Conventionnellement, on stocke le bundle de l"Autorité de Certification approuvé dans le répertoire
<WAPT>\ssl\server.
La Console WAPT comporte une fonction pour faciliter la récupération initiale de la chaîne de certificats du serveur et la stocker au format .pem dans le fichier
<WAPT>\ssl\server\<FQDN serveur>.
Il est de la responsabilité de l"Administrateur de s'assurer que la chaîne ainsi récupérée est authentique.
Il est également possible de récupérer la chaîne de certificats du serveur et de renseigner le paramètre
verify_cert avec la commande :command:`wapt-get enable-check-certificate.
Le processus de signature du paquet est lancé lors des actions suivantes :
Action wapt-get.exe build-upload <directory>.
Action wapt-get.exe sign-package <path-to-package-file.wapt>.
Sauvegarder un paquet host dans la Console WAPT.
Editer ou sauvegarder un paquet dans la console WAPT.
Importer un paquet depuis un dépôt externe.
Créer un paquet avec l'assistant de configuration.
Fichier ZIP du paquet WAPT.
Clé privée RSA du signataire encodée en format .pem et chiffrée (par l'algorithme aes-256-cbc de OpenSSL si la clé a été créée dans la console WAPT).
Certificat X509 du signataire correspondant à la clé privée.
Si le paquet à signer contient un fichier
setup.py, le certificat X509 DOIT avoir l'extension advanced Key Usage : codeSigning (220.127.116.11.18.104.22.168.3) ;
Le fichier
control d'un paquet décrit les métadonnées du paquet, en particulier son nom, sa version, ses dépendances et ses conflits. C'est la fiche d'identité du paquet.
Ces métadonnées sont primitivement utilisées par l'agent WAPT pour déterminer si un paquet doit être mis à jour, et quels autres paquets doivent être installés ou désinstallés préalablement.
Ces informations sont donc signées pour garantir aux Postes client leur intégrité et leur authenticité.
Etapes du processus :
Les attributs
signed_attributes,
signer,
signature_date,
signer_fingerprintsont ajoutés à la structure du fichier
control:
signed_attributes: liste séparée par des virgules des noms des attributs pris en compte dans la signature ;
signer: Nom commun du détenteur du certificat pour information ;
signature_date: date et heure en cours (UTC) sous la forme "%Y-%m-%dT%H:%M:%S" ;
signer_fingerprint: : empreinte
sha256encodée en hexadécimal du certificat du signataire obtenue avec la fonction fingerprint incluse dans la classe cryptography.x509.Certificate.
-
Les attributs signés de la structure de contrôle sont encodés en JSON, sans espace ni saut de ligne, et triés par ordre alphabétique.
Le JSON BLOB résultant est signé avec un hachage sha256 et un remplissage PKCS#1 v1.5.
La signature est encodée en base64 et stockée dans le JSON dans l'attribut
signaturedu fichier
control.
Les attributs du fichier control sont signés et sérialisés en JSON. Le résultat est stocké dans le fichier
<WAPT>\controldu paquet WAPT.
Le certificat X509 sérialisé PEM du détenteur du certificat est stocké dans le fichier
<WAPT>\certificate.crtdu paquet WAPT.
Les empreintes sha256 de tous les fichiers contenus dans le paquet WAPT sont encodées en hexadécimal et stockées sous la forme d'une liste JSON [(nom du fichier, hachage),] dans le fichier
<WAPT>\manifest.sha256du paquet WAPT.
Le contenu du fichier
<WAPT>\manifest.sha256est signé avec la clé privée de l"Administrateur (clé RAS 2048 bits), avec un hachage sha256 et un remplissage PKCS#1 v1.5 :
La procédure de signature fait appel à la fonction sign de la classe cryptography.rsa.RSAPrivateKey.signer.
cryptography.rsa.RSAPrivateKey.signer repose sur les fonctions OpenSSL de EVP_DigestSignInit.
-
La signature est encodée en base64 et stockée dans le fichier
<WAPT>\signature.sha256du paquet WAPT.
La vérification a lieu :
Lors de la mise à jour du fichier d"
indexdes paquets disponibles sur le client WAPT à partir de l'index
Packagesdu dépôt.
Lorsqu'une signature de paquet est vérifiée (installation, téléchargement) lorsqu'elle n'est pas en mode développement, c'est-à-dire si l'installation se fait à partir d'un fichier ZIP et non d'un répertoire de développement.
La vérification consiste à :
Lire les attributs du fichier control depuis le fichier
<WAPT>\controldu ZIP du paquet.
Récupérer le certificat X509 du signataire depuis le fichier
<WAPT>\certificate.crtdu ZIP du paquet.
Décoder l'attribut signature du control depuis le format base64.
Construire une structure JSON avec les attributs devant être signés (tels que définis dans la classe PackageEntry).
Vérifier si la clé publique du certificat du titulaire peut vérifier le hachage de la liste structurée des attributs JSON et la signature du fichier
control, en utilisant le hachage sha256 et le remplissage PKCS#1 v1.5.
Vérifier si le certificat est de confiance (soit présent en tant que tel dans les certificats de confiance, soit signé par une Autorité de Certification de confiance).
Dans le cas où nous devons vérifier les attributs sans avoir le paquet WAPT à disposition, nous récupérons la liste des certificats des détenteurs potentiels de certificats à partir du fichier d'index
Packages sur le dépôt WAPT. Les certificats sont nommés
ssl/<hexadecimal formated certificate fingerprint>.crt.
Un attribut de la structure
control du paquet indique l'empreinte du certificat du signataire du fichier
control.
La vérification a lieu :
Lors de l'installation d'un paquet sur un Poste client.
Lors de l'édition d'un paquet existant.
Lors de l'import d'un paquet depuis un dépôt externe (si option cochée dans la console).
La vérification consiste à :
Récupérer le certificat X509 du signataire depuis le fichier
<WAPT>\certificate.crtdu ZIP du paquet.
Vérifier que le certificat a été signé par une autorité de confiance dont le certificat est présent dans le fichier
ssldu client WAPT.
Vérifier la signature du fichier
<WAPT>\manifest.sha256avec la clé publique.
Depuis la console, les Administrateurs peut déclencher des actions directes sur le client WAPT, s'il est connecté au serveur par le mode Websockets.
La console WAPT signe ces actions avec la clé et le certificat de l"Administrateur avant de les envoyer au serveur WAPT en utilisant une requête HTTPS POST ; la requête est ensuite transmise aux clients WAPT ciblés.
Les actions possibles sont :
trigger_host_update.
trigger_host_upgrade.
trigger_install_packages.
trigger_remove_packages.
trigger_forget_packages.
trigger_cancel_all_tasks.
trigger_host_register.
start_waptexit.
show_message.
trigger_host_update_server_status.
trigger_change_description.
trigger_waptservicerestart.
unregister_computer.
trigger_gpupdate.
trigger_waptwua_scan.
trigger_waptwua_download.
trigger_waptwua_install.
trigger_waptwua_uninstall.
trigger_host_audit.
trigger_audit_packages.
trigger_cleanmgr.
trigger_host_reboot.
trigger_host_shutdown.
trigger_session_setup.
run_wol.
get_tasks_status.
L'action est définie par son nom et des attributs dépendants de l'action. Les attributs sont uuid, action, force, notify_server, et packages (pour les actions impliquant une liste de paquets).
Les attributs
signed_attributes,
signer,
signature_date,
signer_certificatesont ajoutés à la structure de l'action :
signed_attributes: liste des noms des attributs qui sont signés.
signer: Subject.COMMON_NAME du titulaire du certificat.
signature_date: date et heure en cours (UTC) sous la forme "%Y-%m-%dT%H:%M:%S".
signer_certificate: certificat X509 du titulaire encodé en base64.
-
La structure est encodée en JSON.
La signature du JSON est calculée à partir de la clé privée RSA du
signeren utilisant un algorithme de hachage sha256 et un remplissage PKCS1 v1.5.
La signature est encodée en base64 et stockée dans le JSON dans l'attribut
signature.
Depuis la console, les Administrateurs peut déclencher des actions directes sur le client WAPT, s'il est connecté au serveur par le mode Websockets.
Les actions sont encodées en JSON, signées avec la clé et le certificat de l"Administrateur et relayées vers le client WAPT visé par le serveur WAPT.
L'action get_tasks_status ne demande pas d'authentification SSL.
Sur réception d'un évènement par la connexion Websocket du client WAPT :
Le certificat X509 du signataire de l'action est extrait du json (format PEM).
Le client WAPT teste si le certificat est un certificat de confiance, c'est-à-dire présent dans
<WAPT>\sslou signé par une autorité de confiance (certificat de l'autorité présent dans
<WAPT>\ssl).
Le client WAPT teste si le certificat peut vérifier la signature présente dans la structure JSON de l'action ce qui consiste en :
Extraire la signature encodée en base64 dans le json depuis l'attribut
signaturedans le fichier JSON.
Extraire la date de signature formatée sous la forme "%Y-%m-%dT%H:%M:%S" depuis l'attribut
signature_date.
Vérifier que la date de signature n'est pas trop ancienne ou dans le futur de plus de 10 minutes.
Reconstruire une représentation JSON des attributs de l'action.
Vérifier que la clé publique du certificat peut vérifier le JSON avec la signature en utilisant un algorithme de hachage sha256 et un remplissage PKCS1 v1.5.
-
Pour chaque paquet, une somme md5 du paquet est calculée et disponible dans l'index
Packages du dépôt.
Lors de l'installation d'un paquet, le client vérifie si le paquet est déjà disponible localement dans le répertoire
<WAPT>\cache.
Si le fichier est présent, sa somme md5 est comparée avec la somme md5 présente dans l'index. Si elles diffèrent, le paquet en cache local est effacé.
Important
Cette somme md5 ne sert qu'à s'assurer qu'un paquet a été téléchargé complètement.
La vérification de la signature du paquet sera utilisé à la place de la somme md5et d'être effectivement assuré de l'intégrité et de l'authenticité du paquet.