Scroll to navigation

KEYCTL(2) Gestion des clés sous Linux KEYCTL(2)

NOM

keyctl - Manipuler la gestion des clés du noyau

SYNOPSIS

#include <sys/types.h>
#include <keyutils.h>
long keyctl(int operation, ...);
/* Pour un appel direct à l'aide de syscall(2) : */
#include <asm/unistd.h>
#include <linux/keyctl.h>
#include <unistd.h>
long syscall(__NR_keyctl, int operation, __kernel_ulong_t arg2,
             __kernel_ulong_t arg3, __kernel_ulong_t arg4,
             __kernel_ulong_t arg5);

Aucune enveloppe n'est fournie pour la glibc pour cet appel système ; voir les NOTES.

DESCRIPTION

keyctl() permet aux programmes de l'espace utilisateur de manipuler des clés.

L'opération qu'effectue keyctl() dépend de la valeur du paramètre operation. Chacune de ces opérations fait partie de l'enveloppe de la bibliothèque libkeyutils (fournie par le paquet keyutils) en tant que fonctions individuelles (indiquées ci-dessous) pour permettre au compilateur de vérifier les types.

Les valeurs autorisées pour operation sont :

KEYCTL_GET_KEYRING_ID (depuis Linux 2.6.10)
Associer l'identifiant d'une clé spéciale à celui d'une clé réelle pour ce processus.
Cette opération recherche la clé spéciale dont l'identifiant est fourni dans arg2 (transmis à key_serial_t). Si la clé spéciale est trouvée, l'identifiant de la clé réelle correspondante est renvoyé en tant que résultat de la fonction. Les valeurs suivantes peuvent être indiquées dans arg2 :
KEY_SPEC_THREAD_KEYRING
Pour indiquer le trousseau spécifique au thread du thread appelant. Voir thread-keyring(7).
KEY_SPEC_PROCESS_KEYRING
Pour indiquer le trousseau spécifique au processus de l'appelant. Voir process-keyring(7).
KEY_SPEC_SESSION_KEYRING
Pour indiquer le trousseau spécifique à la session de l'appelant. Voir session-keyring(7).
KEY_SPEC_USER_KEYRING
Pour indiquer le trousseau spécifique à l'UID de l'appelant. Voir user-keyring(7).
KEY_SPEC_USER_SESSION_KEYRING
Pour indiquer le trousseau spécifique à la session de l'UID de l'appelant. Voir user-session-keyring(7).
KEY_SPEC_REQKEY_AUTH_KEY (depuis Linux 2.6.16)
Cela indique la clé d'autorisation créée par request_key(2) et passée au processus qu'il produit pour générer une clé. Cette clé n'est disponible que dans un programme à la manière de request-key(8) où une clé d'autorisation a été passée par le noyau et cesse d’être disponible lorsque la clé demandée a été instanciée ; voir request_key(2).
KEY_SPEC_REQUESTOR_KEYRING (depuis Linux 2.6.29)
Cela indique l'identifiant de la clé pour le trousseau de destination request_key(2). Ce trousseau n'est disponible que dans un programme dans le style de request-key(8) où une clé d'autorisation a été passée par le noyau et cesse d’être disponible une fois que la clé demandée a été instanciée ; voir request_key(2).
Si la clé indiquée dans arg2 n'existe pas, le comportement dépend de la valeur de arg3 (diffusée dans int). Si arg3 contient une valeur non nulle — et s'il est utile de le faire (comme pour rechercher un utilisateur, une session utilisateur ou une clé de session) —, une nouvelle clé est créée et son identifiant de clé réelle est renvoyé en tant que résultat de la fonction. Sinon, l'opération échoue avec l'erreur ENOKEY.
Si un identifiant de clé valable est indiqué dans arg2 et si la clé existe, cette opération renvoie simplement l'identifiant de la clé. Si la clé n'existe pas, l'appel échoue avec l'erreur ENOKEY.
L'appelant doit avoir le droit search sur un trousseau pour qu’il soit trouvable.
Les paramètres arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_get_keyring_ID(3).
KEYCTL_JOIN_SESSION_KEYRING (depuis Linux 2.6.10)
Remplacer le trousseau de la session à laquelle le processus est rattaché par un nouveau trousseau de session.
Si arg2 vaut NULL, un trousseau anonyme dont la description est « _ses » est créé et le processus est inscrit à ce trousseau en tant que trousseau de sa session, remplaçant le trousseau de la session précédente.
Sinon, arg2 (diffusé dans char *) est traité comme la description (le nom) d'un trousseau et le comportement est ainsi :
  • Si un trousseau ayant une description correspondante existe, le processus tentera de s'inscrire à ce trousseau en tant que trousseau de session si c'est possible ; sans quoi une erreur est renvoyée. Pour s'inscrire au trousseau, l'appelant doit avoir le droit search sur le trousseau.
  • Si un trousseau avec une description correspondante n'existe pas, un nouveau trousseau ayant la description indiquée est créé et le processus est inscrit à ce trousseau en tant que trousseau de session.
Les paramètres arg3, arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils par la fonction keyctl_join_session_keyring(3).
KEYCTL_UPDATE (depuis Linux 2.6.10)
Mettre à jour la charge utile des données d'une clé.
Le paramètre arg2 (diffusé sur key_serial_t) indique l'identifiant de la clé à mettre à jour. Le paramètre arg3 (diffusé sur void *) pointe vers la nouvelle charge utile et arg4 (diffusé sur size_t) contient la taille de la nouvelle charge utile (en octets).
L'appelant doit avoir les droits write sur la clé indiquée et le type de clé doit gérer les mises à jour.
Une clé instanciée négativement (voir la description de KEYCTL_REJECT) peut être instanciée positivement avec cette opération.
Le paramètre arg5 est ignoré.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_update(3).
KEYCTL_REVOKE (depuis Linux 2.6.10)
Révoquer la clé dont l'identifiant est fourni dans arg2 (diffusé sur key_serial_t). La clé est vouée à aller à la poubelle ; elle ne sera plus trouvable et ne sera plus disponible pour de futures opérations. Les futures tentatives d'utiliser la clé échoueront avec l'erreur EKEYREVOKED.
L'appelant doit avoir les droits write ou setattr sur la clé.
Les paramètres arg3, arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_revoke(3).
KEYCTL_CHOWN (depuis Linux 2.6.10)
Changer le propriétaire (identifiant de l'utilisateur et du groupe) d'une clé.
Le paramètre arg2 (diffusé sur key_serial_t) contient l'identifiant de la clé. Le paramètre arg3 (diffusé sur uid_t) contient l'identifiant du nouvel utilisateur (ou -1 s'il ne doit pas être modifié). Le paramètre arg4 (diffusé sur gid_t) contient l'identifiant du nouveau groupe (ou -1 s'il ne doit pas être modifié).
La clé doit accorder le droit setattr à l'appelant.
Pour pouvoir modifier l'identifiant utilisateur ou utiliser un identifiant de groupe dont l'appelant n'est pas membre, l'appelant doit avoir la capacité CAP_SYS_ADMIN (voir capabilities(7)).
Si l'identifiant utilisateur doit être modifié, le nouvel utilisateur doit avoir un quota suffisant pour accepter la clé. La déduction du quota sera déplacée de l’ancien utilisateur vers le nouveau à condition que l’UID ait changé.
Le paramètre arg5 est ignoré.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_chown(3).
KEYCTL_SETPERM (depuis Linux 2.6.10)
Passer les droits de la clé dont l'identifiant est fourni dans le paramètre arg2 (diffusé sur key_serial_t) à ceux fournis dans le paramètre arg3 (diffusé sur key_perm_t).
Si l'appelant n'a pas la capacité CAP_SYS_ADMIN, il ne peut modifier que les droits des clés qu'il possède. (Plus précisément, l’UID du système de fichiers de l’appelant doit correspondre à l’UID de la clé.)
La clé doit accorder le droit setattr à l'appelant indépendamment de ses capacités.
Les droits dans arg3 indiquent les masques des opérations disponibles pour chacune des catégories suivantes d'utilisateur :
possessor (depuis Linux 2.6.14)
Il s'agit des droits accordés à un processus possédant la clé (en tant qu'il est rattaché à un des trousseaux du processus trouvables) ; voir keyrings(7).
user
Il s'agit du droit accordé à un processus dont l'identifiant utilisateur du système de fichiers correspond à celui de la clé.
group
Il s'agit du droit accordé au processus dont l'identifiant de groupe du système de fichiers ou un de ses identifiants de groupes supplémentaires correspond à celui de la clé.
other
Il s'agit du droit accordé aux autres processus qui ne rentrent pas dans les catégories user et group.
Les catégories user, group et other sont exclusives : si un processus rentre dans la catégorie user, il ne recevra pas de droits dans la catégorie group ; s'il rentre dans la catégorie user ou group, il ne recevra aucun droit de la catégorie other.
La catégorie possessor accorde des droits qui s'ajoutent à ceux accordés en vertu des catégories user, group ou other.
Chaque masque de droits pèse huit bits, dont seuls six sont actuellement utilisés. Les droits disponibles sont :
view
Droit de lire les attributs d'une clé.
Ce droit est nécessaire pour l'opération KEYCTL_DESCRIBE.
Les bits de droit pour chaque catégorie sont KEY_POS_VIEW, KEY_USR_VIEW, KEY_GRP_VIEW et KEY_OTH_VIEW.
read
Lire la charge utile d'une clé.
Ce droit est nécessaire pour l'opération KEYCTL_READ.
Les bits de droit pour chaque catégorie sont KEY_POS_READ, KEY_USR_READ, KEY_GRP_READ et KEY_OTH_READ.
write
Mettre à jour ou instancier une clé. Pour un trousseau, attacher ou détacher des clés d'un trousseau.
Ce droit est nécessaire pour les opérations KEYCTL_UPDATE, KEYCTL_REVOKE, KEYCTL_CLEAR, KEYCTL_LINK et KEYCTL_UNLINK.
Les bits des droits pour chaque catégorie sont KEY_POS_WRITE, KEY_USR_WRITE, KEY_GRP_WRITE et KEY_OTH_WRITE.
search
Rechercher dans les trousseaux et rendre les clés trouvables. Les recherches ne peuvent parcourir des trousseaux imbriqués que si les droits search y sont positionnés.
Ce droit est nécessaire pour les opérations KEYCTL_GET_KEYRING_ID, KEYCTL_JOIN_SESSION_KEYRING, KEYCTL_SEARCH et KEYCTL_INVALIDATE.
Les bits de droit pour chaque catégorie sont KEY_POS_SEARCH, KEY_USR_SEARCH, KEY_GRP_SEARCH et KEY_OTH_SEARCH.
link
Rattacher une clé ou un trousseau.
Ce droit est nécessaire pour les opérations KEYCTL_LINK et KEYCTL_SESSION_TO_PARENT.
Les bits des droits pour cette catégorie sont KEY_POS_LINK, KEY_USR_LINK, KEY_GRP_LINK et KEY_OTH_LINK.
setattr (depuis Linux 2.6.15).
Modifier un identifiant d'utilisateur, de groupe ou le masque de droits d'une clé.
Ce droit est nécessaire pour les opérations KEYCTL_REVOKE, KEYCTL_CHOWN et KEYCTL_SETPERM.
Les bits de droits pour chaque catégorie sont KEY_POS_SETATTR, KEY_USR_SETATTR, KEY_GRP_SETATTR et KEY_OTH_SETATTR.
Par commodité, les macros suivantes sont définies en tant que masques pour tous les bits de droits de chacune des catégories de l'utilisateur : KEY_POS_ALL, KEY_USR_ALL, KEY_GRP_ALL et KEY_OTH_ALL.
Les paramètres arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_setperm(3).
KEYCTL_DESCRIBE (depuis Linux 2.6.10)
Obtenir une chaîne décrivant les attributs d'une clé indiquée.
L'identifiant de la clé à décrire est indiqué dans arg2 (diffusé sur key_serial_t). La chaîne de description est renvoyée dans le tampon vers lequel pointe arg3 (diffusé sur char *) ; arg4 (diffusé sur size_t) indique la taille de ce tampon en octets.
La clé doit accorder le droit view à l'appelant.
La chaîne renvoyée se termine par NULL et contient les informations suivantes sur la clé :

type;uid;gid;perm;description
Dans ce qui précède, type et description sont des chaînes, uid et gid sont des chaînes décimales et perm est un masque de droits hexadécimal. La chaîne de description est écrite dans le format suivant :
%s;%d;%d;%08x;%s
Note : l'objectif est d'étendre la chaîne de description dans les futures versions du noyau. En particulier, le champ description ne contiendra pas de point-virgule ; elle doit être analysée en partant de la fin pour chercher le dernier point-virgule. Cela permettra, à l'avenir, d'insérer des champs délimités avec des points-virgules.
Une tentative d'écrire dans le tampon n'a lieu que lorsque arg3 n'est pas NULL et quand la taille du tampon indiquée est assez grande pour accepter la chaîne de description (y compris l'octet NULL final). Afin de déterminer si la taille du tampon était trop petite, vérifiez que la valeur de retour de l'opération est supérieure à arg4.
Le paramètre arg5 est ignoré.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_describe(3).
KEYCTL_CLEAR
Vider le contenu (à savoir détacher les clés) d'un trousseau.
L'identifiant de la clé (qui doit être de type trousseau) est fourni dans arg2 (diffusé sur key_serial_t).
L'appelant doit avoir le droit write sur le trousseau.
Les paramètres arg3, arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_clear(3).
KEYCTL_LINK (depuis Linux 2.6.10)
Créer un lien d'un trousseau vers une clé.
La clé à rattacher est indiquée dans arg2 (diffusé sur key_serial_t) ; le trousseau est indiqué dans arg3 (diffusé sur key_serial_t).
Si une clé du même type et ayant la même description se trouve déjà rattachée au trousseau, elle est éliminée du trousseau.
Avant de créer le rattachement, le noyau vérifie la profondeur des trousseaux et renvoie les erreurs adéquates si le rattachement crée une boucle ou si la profondeur des trousseaux serait trop importante (la limite de profondeur est définie par la constante KEYRING_SEARCH_MAX_DEPTH du noyau, fixée à 6, et elle est nécessaire pour empêcher les débordements de de la pile du noyau lors d'une recherche récursive de trousseaux).
L'appelant doit avoir le droit link sur la clé à ajouter et celui write sur le trousseau.
Les paramètres arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_link(3).
KEYCTL_UNLINK (depuis Linux 2.6.10)
Supprimer une clé d'un trousseau.
L'identifiant de la clé à détacher est indiqué dans arg2 (diffusé sur key_serial_t) ; l'identifiant du trousseau d'où la clé doit être détachée est indiqué dans arg3 (diffusé sur key_serial_t).
Si la clé n'est pas rattachée au trousseau, cela produit une erreur.
L'appelant doit avoir le droit write sur le trousseau d'où doit être détachée la clé.
Si le dernier rattachement d'une clé est supprimé, cette clé sera mise en destruction.
Les paramètres arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_unlink(3).
KEYCTL_SEARCH (depuis Linux 2.6.10)
Chercher une clé dans l'arborescence d'un trousseau, renvoyer son identifiant et, éventuellement, la rattacher à un trousseau indiqué.
L'arborescence où doit s'effectuer la recherche est indiquée en passant l'identifiant de la clé de tête à arg2 (diffusé sur key_serial_t). La recherche s'effectue en largeur et récursivement.
Les paramètres arg3 et arg4 indiquent la clé à rechercher : arg3 (diffusé en tant que char *) contient le type de clé (une chaîne de caractères se terminant par NULL et mesurant jusqu'à 32 octets en comptant l'octet NULL final), et arg4 (diffusé en tant que char *) contient la description de la clé (une chaîne de caractères se terminant par NULL et mesurant jusqu'à 4096 octets en comptant l'octet NULL final).
Le trousseau d'origine doit autoriser l'appelant à search. Pendant la recherche récursive, seuls les trousseaux accordant le droit search à l'appelant seront explorés. Seules les clés pour lesquelles l'appelant a le droit search seront trouvées.
Si la clé est trouvée, son identifiant est renvoyé en tant que résultat de la fonction.
Si la clé est trouvée et si arg5 (diffusé sur key_serial_t) n'est pas zéro, la clé est rattachée au trousseau indiqué dont l'identifiant est indiqué dans arg5, avec les mêmes contraintes et les mêmes règles que KEYCTL_LINK. Si le trousseau cible indiqué dans arg5 contient déjà une clé rattachée du même type et à la même description, cet attachement sera remplacé par un autre avec la clé trouvée avec cette opération.
Plutôt que des identifiants de trousseaux existants valables, les trousseaux d'origine (arg2) et cible (arg5) peuvent être un des identifiants de trousseau de clés spéciales indiqué dans KEYCTL_GET_KEYRING_ID.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_search(3).
KEYCTL_READ (depuis Linux 2.6.10)
Lire les données de la charge utile (payload) d'une clé.
L'identifiant de la clé dont la charge utile va être lue est indiqué dans arg2 (diffusé sur key_serial_t). Il peut s'agir de l'identifiant d'une clé existante ou un identifiant de clé spéciale listé dans KEYCTL_GET_KEYRING_ID.
La charge utile est mise dans le tampon vers lequel pointe arg3 (diffusé sur char *) ; la taille de ce tampon doit être indiquée dans arg4 (diffusé sur size_t).
Les données renvoyées seront traitées pour être présentées en fonction du type de clé. Par exemple, un trousseau renverra un tableau d'entrées key_serial_t qui représentent les identifiants de toutes les clés qui y sont rattachées. Le type de clé user renverra ses données telles quelles. Si un type de clé n'implémente pas cette fonction, l'opération échoue avec l'erreur EOPNOTSUPP.
Si arg3 n'est pas NULL, autant de données que possible de la charge utile seront copiées dans le tampon. En cas de renvoi d'un succès, la valeur est toujours la taille totale des données de la charge utile. Pour savoir si le tampon était de taille suffisante, vérifiez que la valeur de retour est inférieure ou égale à celle fournie dans arg4.
La clé doit accorder à l'appelant le droit read, ou bien lui accorder le droit search quand elle est recherchée depuis les trousseaux d'un processus (à savoir quand elle est détenue).
Le paramètre arg5 est ignoré.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_read(3).
KEYCTL_INSTANTIATE (depuis Linux 2.6.10)
Instancier (positivement) une clé non instanciée avec une charge utile indiquée
L'identifiant de la clé à instancier est fournie dans arg2 (diffusée sur key_serial_t).
La charge utile de la clé est indiquée dans le tampon vers lequel pointe arg3 (diffusé sur void *) ; la taille de ce tampon est indiquée dans arg4 (diffusée sur size_t).
La charge utile peut être un pointeur NULL et la taille du tampon peut être de 0 si cela est pris en charge par le type de clé (si c'est un trousseau, par exemple).
L'opération peut échouer si les données de charge utile sont dans un mauvais format ou non valables pour toute autre raison.
Si arg5 (diffusé sur key_serial_t) n'est pas zéro, la clé instanciée est rattachée au trousseau dont l'identifiant a été indiqué dans arg5, avec les mêmes contraintes et les mêmes règles que KEYCTL_LINK.
L'appelant doit avoir la clé d'autorisation adéquate, et une fois que la clé non instanciée a été instanciée, la clé d'autorisation est révoquée. Autrement dit, cette opération n'est disponible qu'à partir d'un programme de style request-key(8). Voir request_key(2) pour une explication sur les clés non instanciées et l'instanciation de clés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_instantiate(3).
KEYCTL_NEGATE (depuis Linux 2.6.10)
Instancier négativement une clé non instanciée.
Cette opération est équivalente à l'appel :
keyctl(KEYCTL_REJECT, arg2, arg3, ENOKEY, arg4);
Le paramètre arg5 est ignoré.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_negate(3).
KEYCTL_SET_REQKEY_KEYRING (depuis Linux 2.6.10)
Définir le trousseau par défaut auquel les clés demandées implicitement seront rattachées pour ce thread et renvoyer la configuration précédente. Les requêtes de clé implicites sont celles que des composants du noyau effectuent en interne, comme par exemple lors de l'ouverture de fichiers sur des systèmes de fichiers AFS ou NFS. Le fait de définir un trousseau par défaut produit également des effets lors d'une demande de clé depuis l'espace utilisateur ; voir request_key(2) pour les détails.
Le paramètre arg2 (diffusé sur int) doit contenir une des valeurs suivantes pour indiquer le nouveau trousseau par défaut :
KEY_REQKEY_DEFL_NO_CHANGE
Ne pas modifier le trousseau par défaut. Cela peut servir à rechercher le trousseau par défaut actuel (sans le modifier).
KEY_REQKEY_DEFL_DEFAULT
Cela sélectionne le comportement par défaut qui consiste à utiliser le trousseau spécifique au thread s'il y en a un, ou sinon celui spécifique au processus s'il y en a un, ou bien celui spécifique à la session s'il y en a un, ou sinon celui de la session spécifique de l'identifiant utilisateur, ou celui spécifique à l'utilisateur.
KEY_REQKEY_DEFL_THREAD_KEYRING
Utiliser le trousseau spécifique du thread (thread-keyring(7)) en tant que nouveau trousseau par défaut.
KEY_REQKEY_DEFL_PROCESS_KEYRING
Utiliser le trousseau spécifique au processus (process-keyring(7)) en tant que nouveau trousseau par défaut.
KEY_REQKEY_DEFL_SESSION_KEYRING
Utiliser le trousseau spécifique à la session (session-keyring(7)) en tant que nouveau trousseau par défaut.
KEY_REQKEY_DEFL_USER_KEYRING
Utiliser le trousseau spécifique à l'identifiant utilisateur (user-keyring(7)) en tant que nouveau trousseau par défaut.
KEY_REQKEY_DEFL_USER_SESSION_KEYRING
Utiliser le trousseau de la session spécifique de l'identifiant utilisateur (user-session-keyring(7)) en tant que nouveau trousseau par défaut.
KEY_REQKEY_DEFL_REQUESTOR_KEYRING (depuis Linux 2.6.29)
Utiliser le trousseau du demandeur.
Toutes les autres valeurs ne sont pas valables.
Les paramètres arg3, arg4 et arg5 sont ignorés.
Le paramètre que contrôle cette opération est récupéré par l'enfant de fork(2) et conservé durant un execve(2).
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_set_reqkey_keyring(3).
KEYCTL_SET_TIMEOUT (depuis Linux 2.6.10)
Définir un délai d'expiration sur une clé.
L'identifiant de la clé est indiqué dans arg2 (diffusé sur key_serial_t). La valeur du délai, en seconde à partir de l'heure actuelle, est indiquée dans arg3 (diffusé sur unsigned int). Le délai se mesure par rapport à l'horloge en temps réel.
L'indication d'une valeur de délai de 0 vide les délais existants de la clé.
Le fichier /proc/keys affiche le temps restant avant l'expiration de chaque clé (il s'agit de la seule méthode de recherche du temps de vie d'une clé).
L'appelant doit avoir le droit setattr sur la clé ou détenir un jeton d'autorisation d’instanciation pour cette clé (voir request_key(2)).
La clé et les liens vis-à-vis d'elle seront automatiquement mis à la poubelle après le délai d'expiration. Les futurs essais d'y accéder échoueront avec l'erreur EKEYEXPIRED.
Cette opération ne peut pas être utilisée pour poser des limites à des clés révoquées, expirées ou instanciées négativement.
Les paramètres arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_set_timeout(3).
KEYCTL_ASSUME_AUTHORITY (depuis Linux 2.6.10)
Assumer (ou se débarrasser) de l'autorité pour le thread appelant pour instancier une clé.
Ce paramètre arg2 (diffusé sur key_serial_t) fait assumer l'autorité à un identifiant de clé autre que zéro, ou retire l'autorité grâce à la valeur 0.
Si arg2 n'est pas zéro, il indique un identifiant de clé non instanciée qui devra assumer l'autorité. Cette clé peut alors être instanciée en utilisant KEYCTL_INSTANTIATE, KEYCTL_INSTANTIATE_IOV, KEYCTL_REJECT ou KEYCTL_NEGATE. Quand la clé a été instanciée, le thread se voit automatiquement retirer le pouvoir d'instancier la clé.
Une clé ne peut assumer une autorité que si le thread appelant a dans ses trousseaux la clé d'autorisation associée à la clé (autrement dit, l'opération KEYCTL_ASSUME_AUTHORITY n'est disponible qu'à partir d'un programme du style request-key(8) ; voir request_key(2) pour une explication sur la manière dont cette opération est utilisée). L'appelant doit avoir le droit search sur la clé d'autorisation.
Si la clé indiquée a une clé d'autorisation associée, l'identifiant de cette clé est renvoyé. La clé d'autorisation peut être lue (KEYCTL_READ) pour obtenir les informations d'appel transmises à request_key(2).
Si l'identifiant fourni dans arg2 est 0, l'autorité actuellement assumée est retirée et la valeur 0 est renvoyée.
Le mécanisme KEYCTL_ASSUME_AUTHORITY permet à un programme tel que requestkey(8) d'assumer l'autorité nécessaire pour instancier une nouvelle clé non instanciée créée suite à un appel à request_key(2). Pour plus d'informations, voir request_key(2) et le fichier Documentation/security/keys-request-key.txt des sources du noyau.
Les paramètres arg3, arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_assume_authority(3).
KEYCTL_GET_SECURITY (depuis Linux 2.6.26)
Récupérer l'étiquette de sécurité LSM (Linux Security Module) de la clé indiquée.
L'identifiant de la clé dont l'étiquette doit être récupérée est indiqué dans arg2 (diffusé sur key_serial_t). L'étiquette de sécurité (qui se termine par un octet NULL) sera mis dans le tampon vers lequel pointe arg3 (diffusé sur char *) ; la taille du tampon doit être fournie dans arg4 (diffusée sur size_t).
Si arg3 est indiqué en tant que NULL ou si la taille du tampon indiquée dans arg4 est trop petite, toute la taille de la chaîne de l'étiquette de sécurité (y compris l'octet NULL de fin) est renvoyée en tant que résultat de la fonction et rien n'est copié dans le tampon.
L'appelant doit avoir le droit view sur la clé indiquée.
La chaîne de l'étiquette de sécurité renvoyée sera affichée sous la bonne forme sur le LSM en mode force. Par exemple, avec SELinux, elle peut ressembler à :
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Si aucun LSM n'est en mode force, une chaîne vide est placée dans le tampon.
Le paramètre arg5 est ignoré.
Cette opération est mise à disposition par libkeyutils à l'aide des fonctions keyctl_get_security(3) et keyctl_get_security_alloc(3).
KEYCTL_SESSION_TO_PARENT (depuis Linux 2.6.32)
Remplacer le trousseau de session auquel est enregistré le parent du processus appelant par celui du processus appelant.
Le trousseau sera remplacé dans le processus parent sur les prochains points de transition du parent entre l'espace noyau et l'espace utilisateur.
Le trousseau doit exister et accorder le droit link à l'appelant. Le processus parent doit être single-threaded et appartenir au même utilisateur/groupe effectif que ce processus, et il ne doit pas être set-user-ID ou set-group-ID. L'identifiant utilisateur du trousseau de la session existante du processus parent (s'il en existe un) et celui du trousseau de session de l'appelant doivent correspondre à celui de l'identifiant utilisateur effectif de l'appelant.
Le fait que le processus parent soit touché par cette opération permet à un programme tel qu'un interpréteur de démarrer un processus enfant qui utilise cette opération pour modifier le trousseau de session de l'interpréteur (c'est ce que fait la commande new_session de keyctl(1)).
Les paramètres arg2, arg3, arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_session_to_parent(3).
KEYCTL_REJECT (depuis Linux 2.6.39)
Marquer une clé comme étant instanciée négativement et positionner une durée d'expiration sur la clé. Cette opération ajoute un supplément à l'opération KEYCTL_NEGATE ci-dessus.
L'identifiant de la clé à instancier négativement est indiqué dans arg2 (diffusé sur key_serial_t). Le paramètre arg3 (diffusé sur unsigned int) indique la durée de vie de la clé en seconde. Le paramètre arg4 (diffusé sur unsigned int) indique l'erreur à renvoyer quand une recherche trouve cette clé ; généralement il s'agit de EKEYREJECTED, EKEYREVOKED ou EKEYEXPIRED.
Si arg5 (diffusé sur key_serial_t) n'est pas nul, la clé instanciée négativement est rattachée au trousseau dont l'identifiant est indiqué dans arg5, avec les mêmes contraintes et les mêmes règles que KEYCTL_LINK.
L'appelant doit avoir la clé d'autorisation adéquate. Autrement dit, cette opération n'est disponible qu'à partir d'un programme dans le style request-key(8). Voir request_key(2).
L'appelant doit avoir la clé d'autorisation adéquate, et une fois que la clé non instanciée a été instanciée, la clé d'autorisation est révoquée. Autrement dit, cette opération n'est disponible qu'à partir d'un programme de style request-key(8). Voir request_key(2) pour une explication sur les clés non instanciées et l'instanciation de clés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_reject(3).
KEYCTL_INSTANTIATE_IOV (depuis Linux 2.6.39)
Instancier une clé non instanciée avec la charge utile indiquée à l'aide d'un vecteur de tampons.
Cette opération est la même que KEYCTL_INSTANTIATE, mais les données de la charge utile sont indiquées sous forme d'un tableau de structures iovec :

struct iovec {
    void  *iov_base;    /* Début de l'adresse du tampon */
    size_t iov_len;     /* Taille du tampon (en octets) */
};

    

Le pointeur vers le vecteur de charge utile est indiqué dans arg3 (diffusé en tant que const struct iovec *). Le nombre d'éléments du vecteur est indiqué dans arg4 (diffusé en tant que unsigned int).
arg2 (identifiant de clé) et arg5 (identifiant de trousseau) sont interprétés avec KEYCTL_INSTANTIATE.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_instantiate_iov(3).
KEYCTL_INVALIDATE (depuis Linux 3.5)
Marquer une clé comme non valable.
L'identifiant de la clé à rendre non valable est indiqué dans arg2 (diffusé sur key_serial_t).
Pour rendre une clé non valable, l'appelant doit avoir le droit search sur la clé.
Cette opération marque la clé comme non valable et programme sa mise immédiate à la corbeille. Le ramasse-miettes, supprime les clés non valables de tous les trousseaux et efface la clé quand son nombre de références atteint 0. Après cette opération, cette clé sera ignorée par toutes les recherches, même si elle n'est pas encore effacée.
Les clés marquées comme non valables deviennent aussitôt invisibles pour les opérations de clé normales, bien qu'elle soient encore visibles dans /proc/keys (avec un drapeau « i ») jusqu'à ce qu'elles soient totalement supprimées.
Les paramètres arg3, arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_invalidate(3).
KEYCTL_GET_PERSISTENT (depuis Linux 3.13)
Récupérer le trousseau persistant (persistent-keyring(7)) d'un utilisateur indiqué et le rattacher au trousseau indiqué.
L'identifiant utilisateur est indiqué dans arg2 (diffusé sur uid_t). Si la valeur -1 est indiquée, l'identifiant de l'utilisateur réel de l'appelant est utilisé. L'identifiant du trousseau de destination est indiqué dans arg3 (diffusé sur key_serial_t).
L'appelant doit avoir la capacité CAP_SETUID dans son espace de noms utilisateur afin de récupérer le trousseau persistant pour un identifiant utilisateur qui ne correspond pas à l'identifiant utilisateur réel ou effectif de l'appelant.
Si l'appel réussit, un lien vers le trousseau persistant est ajouté au trousseau dont l'identifiant a été indiqué dans arg3.
L'appelant doit avoir le droit write sur le trousseau.
Le trousseau persistant sera créé par le noyau s'il n'existe pas encore.
Chaque fois que l'opération KEYCTL_GET_PERSISTENT est effectuée, le trousseau persistant aura un délai d'expiration réinitialisé à la valeur dans :

/proc/sys/kernel/keys/persistent_keyring_expiry

    

Lorsque le délai est atteint, le trousseau persistant sera supprimé et son contenu pourra être collecté par le ramasse-miettes.
Des trousseaux persistants ont été ajoutés à Linux dans le noyau version 3.13.
Les paramètres arg4 et arg5 sont ignorés.
Cette opération est mise à disposition par libkeyutils à l'aide de la fonction keyctl_get_persistent(3).
KEYCTL_DH_COMPUTE (depuis Linux 4.7)
Calculer la clé secrète Diffie-Hellman partagée ou la clé publique, en appliquant éventuellement une fonction de dérivation de clé (KDF) au résultat.
Le paramètre arg2 est un pointeur vers un ensemble de paramètres contenant les numéros de série de trois clés « utilisateur » utilisés dans le calcul Diffie-Hellman, empaquetés dans une structure de la forme suivante :

struct keyctl_dh_params {
    int32_t private; /* La clé privée locale */
    int32_t prime; /* Le nombre premier, connue des deux côtés */
    int32_t base;  /* L'entier de base : soit un générateur partagé,
                      soit la clé publique distante */
};

    

Chacune des trois clés indiquées dans cette structure doit accorder le droit read à l'appelant. Les charges utiles de ces clés sont utilisées pour calculer le résultat Diffie-Hellman ainsi :
base ^ private mod prime
Si la base est le générateur partagé, le résultat est la clé publique locale. Si la base est la clé publique distante, le résultat est le code secret partagé.
Le paramètre arg3 (diffusé sur charfP) pointe vers un tampon où est mis le résultat du calcul. La taille de ce tampon est indiquée dans arg4 (diffusé sur size_t).
Le tampon doit être assez grand pour accueillir les données de sortie, sans quoi une erreur est renvoyée. Si arg4 vaut zéro, le tampon n'est pas utilisé et l'opération renvoie la taille minimale requise du tampon (à savoir la longueur du nombre premier).
Les calculs Diffie-Hellman peuvent être effectués dans l'espace utilisateur mais exigent une bibliothèque multiprécision d'entiers (MPI). Le déplacement de l'implémentation dans le noyau donne accès à l'implémentation MPI du noyau et permet d'accéder à la sécurisation et à l'accélération matérielle.
L'ajout de la prise en charge du calcul DH à l'appel système keyctl() a été considéré comme convenable grâce à l'utilisation de l'algorithme DH pour faire dériver les clés partagées ; cela permet aussi au type de clé de déterminer l'implémentation DH adéquate (logicielle ou matérielle).
Si le paramètre arg5 vaut NULL, le résultat DH lui-même est renvoyé. Sinon, (depuis Linux 4.12), il s'agit d'un pointeur vers une structure qui indique les paramètres de l'opération KDF à appliquer :

struct keyctl_kdf_params {
    char *hashname;     /* Nom de l'algorithm de hachage */
    char *otherinfo;    /* SP800-56A OtherInfo */
    __u32 otherinfolen; /* Taille des données otherinfo */
    __u32 __spare[8];   /* Réservé */
};

    

Le champ hashname est une chaîne se terminant par NULL qui indique un nom de hachage (disponible dans l'API de chiffrement du noyau ; la liste des hachages disponibles est plutôt difficile à examiner ; veuillez vous reporter à la documentation de la « Kernel Crypto API Architecture » pour des informations sur la manière dont les noms de hachage sont construits, et aux sources et à la configuration de votre noyau concernant les chiffrements et les modèles de type CRYPTO_ALG_TYPE_SHASH disponibles) à appliquer au résultat DH dans l'opération KDF.
Le champ otherinfo consiste dans des données OtherInfo comme décrit dans la section 5.8.1.2 de SP800-56A et il est spécifique à l'algorithme. Ces données sont concaténées avec le résultat de l'opération DH et elles sont fournies comme entrée de l'opération KDF. Leur taille est fournie dans le champ otherinfolen et limitée à la constante KEYCTL_KDF_MAX_OI_LEN définie dans security/keys/internal.h à la valeur 64.
Le champ __spare est actuellement inusité. Il était ignoré jusqu'à Linux 4.13 (mais il est encore visible par l'utilisateur puisqu'il est copié dans le noyau) et il devrait contenir des zéros depuis Linux 4.13.
L'implémentation KDF se conforme à SP800-56A et à SP800-108 (le compteur KDF).
Cette opération est mise à disposition par libkeyutils (depuis la version 1.5.10 jusqu'à aujourd'hui) à l'aide de la fonction keyctl_dh_compute(3) et de keyctl_dh_compute_alloc(3).
KEYCTL_RESTRICT_KEYRING (depuis Linux 4.12)
Appliquer une restriction de rattachement de clé à un trousseau dont l'identifiant est fourni dans arg2 (diffusé sur key_serial_t). L'appelant doit avoir le droit setattr sur la clé. Si arg3 vaut NULL, toute tentative d'ajout au trousseau est bloquée ; sinon il contient un pointeur vers une chaîne contenant le nom du type de clé et arg4 contient un pointeur vers une chaîne contenant la restriction spécifique au type de clé. À partir de Linux 4.12, seul le type « asymmetric » a des restrictions définies :
builtin_trusted
N'autoriser que les clés signées par une clé rattachée au trousseau interne (« .builtin_trusted_keys »).
builtin_and_secondary_trusted
N'autoriser que les clés signées par une clé rattachée à un trousseau secondaire (« .secondary_trusted_keys ») ou, par extension, à une clé du trousseau interne, puisque le deuxième est lié au premier.
key_or_keyring:key
key_or_keyring:key:chain
Si key indique l'identifiant d'une clé de type « asymmetric », seules les clés signées par cette clé sont autorisées.
Si key indique l'identifiant d'un trousseau, seules les clés signées par une clé rattachée à ce trousseau sont autorisées.
Si « :chain » est indiqué, les clés signées par une clé rattachée au trousseau de destination (c'est-à-dire le trousseau dont l'identifiant est indiqué dans le paramètre arg2) sont aussi autorisées.
Remarquez qu'une restriction ne peut être configurée qu'une fois pour le trousseau indiqué ; une fois qu'une restriction est positionnée, elle ne peut pas être contournée.
Le paramètre arg5 est ignoré.

VALEUR RENVOYÉE

Pour qu'un appel réussisse, le code de retour dépend de l'opération :
KEYCTL_GET_KEYRING_ID
L'identifiant du trousseau demandé.
KEYCTL_JOIN_SESSION_KEYRING
L'identifiant du trousseau de la session qu'on vient de rejoindre.
KEYCTL_DESCRIBE
La taille de la description (comprenant l'octet NULL de fin) indépendamment de la taille du tampon fournie.
KEYCTL_SEARCH
L'identifiant de la clé trouvée.
KEYCTL_READ
La quantité de données disponibles dans la clé, indépendamment de la taille du tampon fournie.
KEYCTL_SET_REQKEY_KEYRING
L'identifiant du trousseau par défaut précédent auquel ont été rattachées implicitement les clés sollicitées (un parmi KEY_REQKEY_DEFL_USER_*).
KEYCTL_ASSUME_AUTHORITY
0 si l'identifiant donné valait 0, ou l'identifiant de la clé d'autorisation correspondant à la clé indiquée, si un identifiant de clé autre que zéro a été fourni.
KEYCTL_GET_SECURITY
La taille de la chaîne de l'étiquette de sécurité LSM (y compris l'octet NULL de fin), indépendamment de la taille du tampon fourni.
KEYCTL_GET_PERSISTENT
L'identifiant du trousseau persistant.
KEYCTL_DH_COMPUTE
Le nombre d'octets copiés dans le tampon ou, si arg4 vaut 0, la taille du tampon nécessaire.
Toutes les autres opérations
Zéro.

En cas d'erreur, -1 est renvoyé et errno est positionné adéquatement pour indiquer l'erreur.

ERREURS

EACCES
L'opération demandée n'était pas autorisée.
EAGAIN
operation était KEYCTL_DH_COMPUTE et une erreur s'est produite lors de l'initialisation du module de chiffrement.
EDEADLK
operation était KEYCTL_LINK et le rattachement demandé conduirait à une boucle.
EDEADLK
operation était KEYCTL_RESTRICT_KEYRING et la restriction de trousseau demandée aboutirait à une boucle.
EDQUOT
Le quota de clés de l'utilisateur appelant serait dépassé si la clé était créée ou ajoutée au trousseau.
EEXIST
operation était KEYCTL_RESTRICT_KEYRING et le trousseau fourni dans le paramètre arg2 comporte déjà une restriction.
EFAULT
operation était KEYCTL_DH_COMPUTE et une des actions suivantes a échoué :
copie de la struct keyctl_dh_params, fournie dans le paramètre arg2, depuis l'espace utilisateur ;
copie de la struct keyctl_kdf_params, fournie dans l'argument non NULL arg5, depuis l'espace utilisateur (si le noyau gère l'opération KDF lors du résultat de l'opération DH) ;
copie des données vers lesquelles pointe le champ hashname de la struct keyctl_kdf_params à partir de l'espace utilisateur ;
copie des données vers lesquelles pointe le champ otherinfo de la struct keyctl_kdf_params depuis l'espace utilisateur si le champ otherinfolen n'était pas zéro ;
copie du résultat vers l'espace utilisateur.
EINVAL
operation était KEYCTL_SETPERM et un bit de droit non valable a été indiqué dans arg3.
EINVAL
operation était KEYCTL_SEARCH et la taille de la description dans arg4 (y compris l'octet NULL final) dépassait 4096 octets. La taille de la chaîne (y compris l'octet NULL final) indiquée dans arg3 (le type de clé) ou dans arg4 (la description de la clé) dépassait les limites (respectivement 32 et 4096 octets).
EINVAL (noyaux Linux antérieurs à 4.12)
operation était KEYCTL_DH_COMPUTE, le paramètre arg5 n'était pas NULL.
EINVAL
operation était KEYCTL_DH_COMPUTE et la taille de l’empreinte numérique de l'algorithme de hachage fourni est de zéro.
EINVAL
operation était KEYCTL_DH_COMPUTE et la taille du tampon fournie n'est pas suffisante pour contenir le résultat. Mettez 0 en tant que taille de tampon pour obtenir la taille minimale du tampon.
EINVAL
operation était KEYCTL_DH_COMPUTE et le nom de hachage fourni dans le champ hashname de la struct keyctl_kdf_params vers laquelle pointe le paramètre arg5 est trop grand (la limite est spécifique à l'implémentation et varie entre les versions du noyau, mais elle est considérée comme suffisante pour tous les noms d'algorithmes valables).
EINVAL
operation était KEYCTL_DH_COMPUTE et le champ __spare de la struct keyctl_kdf_params fournie dans le paramètre arg5 contient des valeurs autres que zéro.
EKEYEXPIRED
Une clé expirée a été trouvée ou spécifiée.
EKEYREJECTED
Une clé rejetée a été trouvée ou spécifiée.
EKEYREVOKED
Une clé révoquée a été trouvée ou spécifiée.
ELOOP
operation était KEYCTL_LINK et le rattachement demandé ferait dépasser la profondeur maximale d’imbrication des trousseaux.
EMSGSIZE
operation était KEYCTL_DH_COMPUTE et la longueur du tampon dépasse KEYCTL_KDF_MAX_OUTPUT_LEN (qui est actuellement de 1024) ou le champ otherinfolen de la struct keyctl_kdf_parms fournie dans arg5 dépasse KEYCTL_KDF_MAX_OI_LEN (qui est actuellement de 64).
ENFILE (noyaux Linux avant le 3.13)
operation était KEYCTL_LINK et le trousseau est complet (avant Linux 3.13, l'espace disponible de stockage de rattachements de trousseaux était limité à une seule page mémoire ; depuis Linux 3.13, il n'y a pas de limite fixée).
ENOENT
operation était KEYCTL_UNLINK et la clé à détacher n'est pas rattachée au trousseau.
ENOENT
operation était KEYCTL_DH_COMPUTE et l'algorithme de hachage indiqué dans le champ hashname de la struct keyctl_kdf_params vers laquelle pointe le paramètre arg5 n'a pas été trouvé.
ENOENT
operation était KEYCTL_RESTRICT_KEYRING et le type fourni dans le paramètre arg3 ne gère pas la définition de restrictions de rattachement de clés.
ENOKEY
Aucune clé correspondante n'a été trouvée, ou une clé non valable a été spécifiée.
ENOKEY
La valeur KEYCTL_GET_KEYRING_ID était indiquée dans operation, la clé indiquée dans arg2 n'existait pas et arg3 valait zéro (ce qui veut dire ne pas créer de clé si elle n'existe pas).
ENOMEM
Une des routines de l'allocation mémoire du noyau a échoué lors de l'exécution de l'appel système.
ENOTDIR
Une clé de type trousseau était attendue mais l'identifiant d'une clé de type différent a été fourni.
EOPNOTSUPP
operation était KEYCTL_READ et le type de clé ne gère pas la lecture (par exemple, le type est « login »).
EOPNOTSUPP
operation était KEYCTL_UPDATE et le type de clé ne gère pas les mises à jour.
EOPNOTSUPP
operation était KEYCTL_RESTRICT_KEYRING, le type fourni dans le paramètre arg3 était « asymmetric », et la clé indiquée dans la spécification de la restriction fournie dans arg4 a un autre type que « asymmetric » ou « keyring ».
EPERM
operation était KEYCTL_GET_PERSISTENT, arg2 indiquait un identifiant utilisateur différent de celui de l'utilisateur réel ou effectif du thread appelant, et l'appelant n'avait pas la capacité CAP_SETUID.
EPERM
operation était KEYCTL_SESSION_TO_PARENT et : soit tous les identifiants utilisateur (ou de groupe) du processus parent ne correspondent pas à celui effectif du processus appelant ; soit l'identifiant utilisateur du trousseau de session du parent, ou celui du trousseau de session de l'appelant, ne correspondait pas à l'identifiant de l'utilisateur effectif de l'appelant ; soit le processus parent se compose de plus d'un thread ; soit le processus parent est init(1) ou un thread du noyau.
ETIMEDOUT
operation était KEYCTL_DH_COMPUTE et l'initialisation des modules de chiffrement a dépassé le délai.

VERSIONS

Cet appel système est apparu pour la première fois dans Linux 2.6.10.

CONFORMITÉ

Cet appel système est une extension Linux non standard.

NOTES

Aucune enveloppe pour cet appel système n'est fournie dans la glibc. Une enveloppe est fournie dans la bibliothèque libkeyutils. Quand on utilise une enveloppe de cette bibliothèque, liez-la avec -lkeyutils. Cependant, plutôt que d'utiliser cet appel système directement, vous voudrez probablement utiliser les fonctions de la bibliothèque mentionnées dans les descriptions des opérations individuelles ci-dessus.

EXEMPLES

Le programme ci-dessous fournit un sous-ensemble de fonctions du programme request-key(8) fourni par le paquet keyutils. Pour information, le programme enregistre diverses informations dans un fichier journal.

Comme indiqué dans request_key(2), le programme request-key(8) est appelé avec les paramètres de la ligne de commande qui décrivent une clé à instancier. Le programme exemple récupère et enregistre ces arguments. Le programme endosse l'autorité d'instancier la clé demandée, puis il instancie cette clé.

La session d'interpréteur suivante montre l'utilisation de ce programme. Dans la session, nous compilons le programme, puis nous l'utilisons pour remplacer temporairement le programme request-key(8) standard (remarquez que la désactivation temporaire du programme standard request-key(8) peut ne pas être sure sur certains systèmes). Tant que notre programme exemple est installé, nous utilisons le programme exemple présent dans request_key(2) pour demander une clé.


$ cc -o key_instantiate key_instantiate.c -lkeyutils
$ sudo mv /sbin/request-key /sbin/request-key.backup
$ sudo cp key_instantiate /sbin/request-key
$ ./t_request_key user mykey somepayloaddata
L'identifiant de clé est 20d035bf
$ sudo mv /sbin/request-key.backup /sbin/request-key


En regardant le fichier journal créé par ce programme, on peut voir les paramètres de la ligne de commande fournis à notre programme exemple :


$ cat /tmp/key_instantiate.log
Time: Mon Nov  7 13:06:47 2016
Command line arguments:
  argv[0]:            /sbin/request-key
  operation:          create
  key_to_instantiate: 20d035bf
  UID:                1000
  GID:                1000
  thread_keyring:     0
  process_keyring:    0
  session_keyring:    256e6a6
Key description:      user;1000;1000;3f010000;mykey
Auth key payload:     somepayloaddata
Destination keyring:  256e6a6
Auth key description: .request_key_auth;1000;1000;0b010000;20d035bf


Les dernières lignes de la sortie ci-dessus montrent que le programme exemple a pu récupérer :

  • la description de la clé à instanciée, qui incluait le nom de la clé (mykey) ;
  • la charge utile de la clé d'autorisation, qui consistait dans des données (somepayloaddata) passées à request_key(2) ;
  • le trousseau de destination indiqué dans l'appel à request_key(2) ;
  • la description de la clé d'autorisation où on peut voir que le nom de la clé correspond à l'identifiant de celle à instancier (20d035bf).

Le programme exemple dans request_key(2) indiquait le trousseau de destination en tant que KEY_SPEC_SESSION_KEYRING. En examinant le contenu de /proc/keys, on peut voir que cela a été transcrit dans l'identifiant du trousseau de destination (0256e6a6) affiché dans le fichier journal ci-dessus ; on peut aussi voir la clé nouvellement créée dont le nom est mykey et l'identifiant est 20d035bf.


$ cat /proc/keys | egrep 'mykey|256e6a6'
0256e6a6 I--Q---  194 perm 3f030000  1000  1000 keyring  _ses: 3
20d035bf I--Q---    1 perm 3f010000  1000  1000 user     mykey: 16


Source du programme

/* key_instantiate.c */
#include <sys/types.h>
#include <keyutils.h>
#include <time.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#ifndef KEY_SPEC_REQUESTOR_KEYRING
#define KEY_SPEC_REQUESTOR_KEYRING      -8
#endif
int
main(int argc, char *argv[])
{
    FILE *fp;
    time_t t;
    char *operation;
    key_serial_t key_to_instantiate, dest_keyring;
    key_serial_t thread_keyring, process_keyring, session_keyring;
    uid_t uid;
    gid_t gid;
    char dbuf[256];
    char auth_key_payload[256];
    int akp_size;       /* Size of auth_key_payload */
    int auth_key;
    fp = fopen("/tmp/key_instantiate.log", "w");
    if (fp == NULL)
        exit(EXIT_FAILURE);
    setbuf(fp, NULL);
    t = time(NULL);
    fprintf(fp, "Time: %s\n", ctime(&t));
    /*
     * Le noyau passe un ensemble fixe de paramètres au programme
     * qu'il exécute ; les récupérer.
     */
    operation = argv[1];
    key_to_instantiate = atoi(argv[2]);
    uid = atoi(argv[3]);
    gid = atoi(argv[4]);
    thread_keyring = atoi(argv[5]);
    process_keyring = atoi(argv[6]);
    session_keyring = atoi(argv[7]);
    fprintf(fp, "Paramètres de la ligne de commande :\n");
    fprintf(fp, "  argv[0]:            %s\n", argv[0]);
    fprintf(fp, "  operation:          %s\n", operation);
    fprintf(fp, "  key_to_instantiate: %jx\n",
            (uintmax_t) key_to_instantiate);
    fprintf(fp, "  UID:                %jd\n", (intmax_t) uid);
    fprintf(fp, "  GID:                %jd\n", (intmax_t) gid);
    fprintf(fp, "  thread_keyring:     %jx\n",
            (uintmax_t) thread_keyring);
    fprintf(fp, "  process_keyring:    %jx\n",
            (uintmax_t) process_keyring);
    fprintf(fp, "  session_keyring:    %jx\n",
            (uintmax_t) session_keyring);
    fprintf(fp, "\n");
    /*
     * Assumer l'autorité pour instancier la clé nommée dans argv[2]
     */
    if (keyctl(KEYCTL_ASSUME_AUTHORITY, key_to_instantiate) == -1) {
        fprintf(fp, "KEYCTL_ASSUME_AUTHORITY a échoué : %s\n",
                strerror(errno));
        exit(EXIT_FAILURE);
    }
    /*
     * Récupérer la description de la clé à instancier
     */
    if (keyctl(KEYCTL_DESCRIBE, key_to_instantiate,
                dbuf, sizeof(dbuf)) == -1) {
        fprintf(fp, "KEYCTL_DESCRIBE a échoué : %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }
    fprintf(fp, "Description de clé :      %s\n", dbuf);
    /*
     * Récupérer la charge utile de la clé d'autorisation, qui est en fait
     * les données d'appel (callout) données à request_key()
     */
    akp_size = keyctl(KEYCTL_READ, KEY_SPEC_REQKEY_AUTH_KEY,
                      auth_key_payload, sizeof(auth_key_payload));
    if (akp_size == -1) {
        fprintf(fp, "KEYCTL_READ a échoué : %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }
    auth_key_payload[akp_size] = '\0';
    fprintf(fp, "Charge utile de la clé d'auth :     %s\n", auth_key_payload);
    /*
     * Par intérêt, récupérer l'identifiant de la clé d'autorisation et
     * l'afficher.
     */
    auth_key = keyctl(KEYCTL_GET_KEYRING_ID,
            KEY_SPEC_REQKEY_AUTH_KEY);
    if (auth_key == -1) {
        fprintf(fp, "KEYCTL_GET_KEYRING_ID a échoué : %s\n",
                strerror(errno));
        exit(EXIT_FAILURE);
    }
    fprintf(fp, "Identifiant de la clé d'auth :       %jx\n", (uintmax_t) auth_key);
    /*
     * Récupérer l'identifiant de clé pour le trousseau de destination
     * request_key(2).
     */
    dest_keyring = keyctl(KEYCTL_GET_KEYRING_ID,
                          KEY_SPEC_REQUESTOR_KEYRING);
    if (dest_keyring == -1) {
        fprintf(fp, "KEYCTL_GET_KEYRING_ID a échoué : %s\n",
                strerror(errno));
        exit(EXIT_FAILURE);
    }
    fprintf(fp, "Trousseau de destination :  %jx\n", (uintmax_t) dest_keyring);
    /*
     * Récupérer la description de la clé d'autorisation. Cela nous permet
     * de voir le type de clé, l'identifiant utilisateur et de groupe, les
     * droits et la description (nom) de la clé. Entre autres choses,
     * on verra que le nom de la clé est une chaîne hexadécimale représentant
     * l'identifiant de la clé à instancier.
     */
    if (keyctl(KEYCTL_DESCRIBE, KEY_SPEC_REQKEY_AUTH_KEY,
                dbuf, sizeof(dbuf)) == -1) {
        fprintf(fp, "KEYCTL_DESCRIBE a échoué : %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }
    fprintf(fp, "Description de la clé d'auth : %s\n", dbuf);
    /*
     * Instancier la clé en utilisant les données de l'appel (callout)
     * fournies dans la charge utile de la clé d'autorisation.
     */
    if (keyctl(KEYCTL_INSTANTIATE, key_to_instantiate,
               auth_key_payload, akp_size + 1, dest_keyring) == -1) {
        fprintf(fp, "KEYCTL_INSTANTIATE a échoué : %s\n",
                strerror(errno));
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

VOIR AUSSI

keyctl(1), add_key(2), request_key(2), keyctl(3), keyctl_assume_authority(3), keyctl_chown(3), keyctl_clear(3), keyctl_describe(3), keyctl_describe_alloc(3), keyctl_dh_compute(3), keyctl_dh_compute_alloc(3), keyctl_get_keyring_ID(3), keyctl_get_persistent(3), keyctl_get_security(3), keyctl_get_security_alloc(3), keyctl_instantiate(3), keyctl_instantiate_iov(3), keyctl_invalidate(3), keyctl_join_session_keyring(3), keyctl_link(3), keyctl_negate(3), keyctl_read(3), keyctl_read_alloc(3), keyctl_reject(3), keyctl_revoke(3), keyctl_search(3), keyctl_session_to_parent(3), keyctl_set_reqkey_keyring(3), keyctl_set_timeout(3), keyctl_setperm(3), keyctl_unlink(3), keyctl_update(3), recursive_key_scan(3), recursive_session_key_scan(3), capabilities(7), credentials(7), keyrings(7), keyutils(7), persistent-keyring(7), process-keyring(7), session-keyring(7), thread-keyring(7), user-keyring(7), user_namespaces(7), user-session-keyring(7), request-key(8)

Les fichiers sources du noyau Documentation/security/keys/ (ou avant Linux 4.13, dans le fichier Documentation/security/keys.txt).

COLOPHON

Cette page fait partie de la publication 5.10 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

TRADUCTION

La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Philippe MENGUAL <jpmengual@debian.org>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.

1 novembre 2020 Linux