Provided by: manpages-fr-extra_20151231_all bug

NOM

       moteur - ENGINE module de support cryptographique

SYNOPSIS

        #include <openssl/engine.h>

        ENGINE *ENGINE_get_first(void);
        ENGINE *ENGINE_get_last(void);
        ENGINE *ENGINE_get_next(ENGINE *e);
        ENGINE *ENGINE_get_prev(ENGINE *e);

        int ENGINE_add(ENGINE *e);
        int ENGINE_remove(ENGINE *e);

        ENGINE *ENGINE_by_id(const char *id);

        int ENGINE_init(ENGINE *e);
        int ENGINE_finish(ENGINE *e);

        void ENGINE_load_openssl(void);
        void ENGINE_load_dynamic(void);
        #ifndef OPENSSL_NO_STATIC_ENGINE
        void ENGINE_load_4758cca(void);
        void ENGINE_load_aep(void);
        void ENGINE_load_atalla(void);
        void ENGINE_load_chil(void);
        void ENGINE_load_cswift(void);
        void ENGINE_load_gmp(void);
        void ENGINE_load_nuron(void);
        void ENGINE_load_sureware(void);
        void ENGINE_load_ubsec(void);
        #endif
        void ENGINE_load_cryptodev(void);
        void ENGINE_load_builtin_engines(void);

        void ENGINE_cleanup(void);

        ENGINE *ENGINE_get_default_RSA(void);
        ENGINE *ENGINE_get_default_DSA(void);
        ENGINE *ENGINE_get_default_ECDH(void);
        ENGINE *ENGINE_get_default_ECDSA(void);
        ENGINE *ENGINE_get_default_DH(void);
        ENGINE *ENGINE_get_default_RAND(void);
        ENGINE *ENGINE_get_cipher_engine(int nid);
        ENGINE *ENGINE_get_digest_engine(int nid);

        int ENGINE_set_default_RSA(ENGINE *e);
        int ENGINE_set_default_DSA(ENGINE *e);
        int ENGINE_set_default_ECDH(ENGINE *e);
        int ENGINE_set_default_ECDSA(ENGINE *e);
        int ENGINE_set_default_DH(ENGINE *e);
        int ENGINE_set_default_RAND(ENGINE *e);
        int ENGINE_set_default_ciphers(ENGINE *e);
        int ENGINE_set_default_digests(ENGINE *e);
        int ENGINE_set_default_string(ENGINE *e, const char *list);

        int ENGINE_set_default(ENGINE *e, unsigned int flags);

        unsigned int ENGINE_get_table_flags(void);
        void ENGINE_set_table_flags(unsigned int flags);

        int ENGINE_register_RSA(ENGINE *e);
        void ENGINE_unregister_RSA(ENGINE *e);
        void ENGINE_register_all_RSA(void);
        int ENGINE_register_DSA(ENGINE *e);
        void ENGINE_unregister_DSA(ENGINE *e);
        void ENGINE_register_all_DSA(void);
        int ENGINE_register_ECDH(ENGINE *e);
        void ENGINE_unregister_ECDH(ENGINE *e);
        void ENGINE_register_all_ECDH(void);
        int ENGINE_register_ECDSA(ENGINE *e);
        void ENGINE_unregister_ECDSA(ENGINE *e);
        void ENGINE_register_all_ECDSA(void);
        int ENGINE_register_DH(ENGINE *e);
        void ENGINE_unregister_DH(ENGINE *e);
        void ENGINE_register_all_DH(void);
        int ENGINE_register_RAND(ENGINE *e);
        void ENGINE_unregister_RAND(ENGINE *e);
        void ENGINE_register_all_RAND(void);
        int ENGINE_register_STORE(ENGINE *e);
        void ENGINE_unregister_STORE(ENGINE *e);
        void ENGINE_register_all_STORE(void);
        int ENGINE_register_ciphers(ENGINE *e);
        void ENGINE_unregister_ciphers(ENGINE *e);
        void ENGINE_register_all_ciphers(void);
        int ENGINE_register_digests(ENGINE *e);
        void ENGINE_unregister_digests(ENGINE *e);
        void ENGINE_register_all_digests(void);
        int ENGINE_register_complete(ENGINE *e);
        int ENGINE_register_all_complete(void);

        int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
        int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
        int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
                long i, void *p, void (*f)(void), int cmd_optional);
        int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
                int cmd_optional);

        int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
        void *ENGINE_get_ex_data(const ENGINE *e, int idx);

        int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);

        ENGINE *ENGINE_new(void);
        int ENGINE_free(ENGINE *e);
        int ENGINE_up_ref(ENGINE *e);

        int ENGINE_set_id(ENGINE *e, const char *id);
        int ENGINE_set_name(ENGINE *e, const char *name);
        int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
        int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
        int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *dh_meth);
        int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *dh_meth);
        int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
        int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
        int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *rand_meth);
        int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
        int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
        int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
        int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
        int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
        int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
        int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
        int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
        int ENGINE_set_flags(ENGINE *e, int flags);
        int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);

        const char *ENGINE_get_id(const ENGINE *e);
        const char *ENGINE_get_name(const ENGINE *e);
        const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
        const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
        const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
        const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
        const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
        const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
        const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
        ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
        ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
        ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
        ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
        ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
        ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
        ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
        ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
        const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
        const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
        int ENGINE_get_flags(const ENGINE *e);
        const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);

        EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
            UI_METHOD *ui_method, void *callback_data);
        EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
            UI_METHOD *ui_method, void *callback_data);

        void ENGINE_add_conf_module(void);

DESCRIPTION

       Ces fonctions créent, manipulent et utilisent des modules cryptographiques sous la forme
       d'objets ENGINE. Ces objets servent de conteneurs pour les implémentations d'algorithmes
       cryptographiques, et ils gèrent un mécanisme de comptage de référence qui les autorisent à
       être chargés de façon dynamique dans l'application exécutée et en dehors.

       La fonctionnalité cryptographique qui peut être fournie par l'implémentation d'un ENGINE
       inclut les abstractions suivantes :

        RSA_METHOD - pour fournir une implémentation RSA alternative
        DSA_METHOD, DH_METHOD, RAND_METHOD, ECDH_METHOD, ECDSA_METHOD,
              STORE_METHOD - identique pour d'autres API d'OpenSSL
        EVP_CIPHER - potentiellement plusieurs algorithmes de chiffrement (indexé par 'nid')
        EVP_DIGEST - potentiellement plusieurs algorithmes de hachage (indexé par 'nid')
        key-loading - chargement des clés EVP_PKEY publiques/privées

   Référence de calculs et traitements
       À cause de la nature modulaire de l'API ENGINE, les pointeurs vers les ENGINE doivent être
       traités comme des références abstraites vers des ressources — c'est-à-dire pas seulement
       comme des pointeurs, mais aussi comme des références vers l'objet ENGINE sous-jacent.
       C'est-à-dire que l'on doit obtenir une nouvelle référence lors de la copie d'un pointeur
       vers un ENGINE si la copie doit être utilisée (et libérée) de façon indépendante.

       Les objets ENGINE ont deux niveaux de comptage de références pour correspondre à la façon
       dont les objets sont utilisés. À plus bas niveau, chaque pointeur ENGINE est
       intrinsèquement une référence structurelle - une référence structurelle est nécessaire
       pour utiliser toute valeur de pointeur, car ce type de référence garantit que la structure
       ne peut pas être désallouée avant que sa référence ne soit libérée.

       Mais, une référence structurelle n'offre aucune garantie que l'ENGINE soit initialisé et
       capable d'utiliser n'importe laquelle de ses implémentations cryptographiques. En effet,
       il est fort probable que la plupart des ENGINE ne puissent pas s'initialiser dans des
       environnements typiques, car les ENGINES sont généralement utilisés pour gérer du matériel
       spécialisé. Pour utiliser une fonctionnalité d'ENGINE, il est nécessaire d'avoir une
       référence fonctionnelle. Cette référence peut être considérée comme une forme spécialisée
       de référence structurelle, car chaque référence fonctionnelle contient de façon implicite
       une référence structurelle. Par contre, pour éviter d'avoir des programmes durs à
       déboguer, il est recommandé de traiter ces deux types de référence indépendamment l'une de
       l'autre. Si une référence fonctionnelle est disponible pour un ENGINE, il est garanti que
       cet ENGINE a été initialisé et est prêt à faire des opérations cryptographiques et restera
       non-initialisable jusqu’à la libération de la référence.

       Structural references

       Ce type de référence de base est utilisé pour instancier de nouveaux ENGINE, itérer sur
       les listes liées d'ENGINE chargés d'OpenSSL, lire les informations d'un ENGINE, etc. Une
       référence structurelle est essentiellement suffisante pour des requêtes ou pour manipuler
       les données d'implémentation d'un ENGINE au lieu d'utiliser ses fonctionnalités.

       La fonction ENGINE_new() renvoie une référence structurelle vers un objet ENGINE vide. Il
       y a d'autres fonctions d'API dans ENGINE qui renvoient une référence structurelle comme :
       ENGINE_by_id(), ENGINE_get_first(), ENGINE_get_last(), ENGINE_get_next(),
       ENGINE_get_prev(). Toute référence structurelle devrait être libérée par un appel
       correspondant à la fonction ENGINE_free() — l'objet ENGINE lui-même ne sera nettoyé et
       désalloué que lorsque la dernière référence structurelle sera libérée.

       On doit aussi remarquer que beaucoup d'appels de fonctions d'API d'ENGINE qui acceptent
       une référence structurelle obtiendront de façon interne une autre référence — en général
       cela ce produira lorsque l'ENGINE sera nécessaire à OpenSSL après le retour de la
       fonction. Exemple : la fonction d'ajout d'un nouvel ENGINE à la liste interne d'OpenSSL
       est ENGINE_add() — si cette actionse termine avec succès, alors OpenSSL aura stocké une
       nouvelle référence structurelle en interne, aussi l'appelant est toujours responsable de
       la libération de ses propres références avec ENGINE_free() quand les fonctions n'en ont
       plus besoin. D'une façon similaire, certaines fonctions libéreront automatiquement la
       référence structurelle qui leur est donnée si une partie du travail de la fonction est de
       faire cela. Exemple : les fonctions ENGINE_get_next() et ENGINE_get_prev() sont utilisées
       pour itérer à travers la liste interne d'ENGINE — elles renverront une nouvelle référence
       structurelle au prochain (ou précédent) ENGINE dans la liste ou NULL si elles sont à la
       fin (ou au début) de la liste, mais, dans tous les cas, la référence structurelle passée à
       la fonction est libérée au nom de l'appelant.

       Pour éclaircir la façon dont une fonction traite les références, on doit toujours
       consulter la documentation en utilisant la page man de cette fonction, ou à défaut
       l’en-tête openssl/engine.h qui contient des indices.

       Références fonctionnelles

       Comme mentionné, les références fonctionnelles existent lorsque la fonctionnalité
       cryptographique d'un ENGINE doit être disponible. Une référence fonctionnelle peut être
       obtenue de plusieurs façons : d'une référence structurelle pré-existante demandée par
       l'ENGINE, ou en demandant à l'ENGINE par défaut d'OpenSSL pour une tâche cryptographique
       donnée.

       Pour obtenir une référence fonctionnelle à partir d'une référence structurelle, appelez la
       fonction ENGINE_init(). Cela renvoie 0 si l'ENGINE n'était pas déjà opérationnel et ne
       pouvait donc pas être initialisé (ex : le manque de pilotes dans le système, pas de
       matériel spécifique attaché, etc), sinon elle renverra autre chose que 0 pour indiquer que
       l'ENGINE est maintenant opérationnel et a alloué une référence fonctionnelle à l'ENGINE.
       Toutes les références fonctionnelles sont libérées en appelant ENGINE_finish() (ce qui
       supprime les références structurelles implicites aussi).

       La deuxième façon de récupérer des références fonctionnelles est de demander à OpenSSL une
       implémentation par défaut pour la tâche voulue, ex : avec ENGINE_get_default_RSA(),
       ENGINE_get_default_cipher_engine(), etc. Celles-ci sont expliquées dans la prochaine
       partie, mais elles ne sont d'habitude pas requises par les programmeurs d'application car
       elles sont utilisées automatiquement quand les spécificités de types de l'algorithme dans
       OpenSSL sont créées et utilisées, comme RSA, DSA, EVP_CIPHER_CTX, etc.

   Implémentations par défaut
       Pour chaque abstraction gérée, le code d'ENGINE maintient une table d'état de contrôle
       interne dans laquelle les implémentations sont disponibles pour une abstraction donnée et
       qui devrait être utilisée par défaut. Ces implémentations sont enregistrées dans les
       tables et indexées par une valeur « nid », parce que les abstractions comme EVP_CIPHER et
       EVP_DIGEST gèrent énormément d'algorithmes et de modes distincts, et les ENGINE peuvent
       arbitrairement tous les prendre en charge. Dans le cas d'autres abstractions comme RSA,
       DSA, etc, il n'y a qu'un seul « algorithme » donc toutes les implémentations sont
       enregistrées de façon implicite en utilisant le même index « nid ».

       Quand une requête d'un ENGINE par défaut pour une abstraction/algorithme/mode est faite
       (par ex. en appelant RSA_new_method(NULL)), un appel « get_default » peut être fait au
       sous-système de l'ENGINE pour traiter l'état de la table correspondante et renvoyer une
       référence fonctionnelle vers un ENGINE initialisé dont l'implémentation devrait être
       utilisée. Si aucun ENGINE ne doit (ou ne peut) être utilisé, elle renverra NULL et
       l'appelant opérera avec un identificateur d'ENGINE NULL — cela correspond à utiliser
       l'implémentation conventionnelle d'un programme. Dans ce cas, OpenSSL fonctionnera de la
       même façon qu'avant que l'API ENGINE n'existe.

       Chaque table d'état a un drapeau pour indiquer si elle a traité cette requête
       « get_default » depuis que la table a été modifiée, car pour traiter cette question elle
       doit itérer à travers tous les ENGINE enregistrés dans la table en essayant de les
       initialiser les uns après les autres, au cas où l'un d'entre eux soit opérationnel. Si
       elle renvoie une référence fonctionnelle vers un ENGINE, elle mettra en cache une autre
       référence pour accélérer le processus en cas de futures requêtes (plus besoin d'avoir à
       itérer sur toute la table). De même, elle mettra en cache une réponse NULL si aucun ENGINE
       n'est disponible pour que les futures requêtes ne fassent pas la même itération, sauf si
       l'état de la table change. Ce comportement peut aussi être changé ; si le drapeau
       ENGINE_TABLE_FLAG_NOINIT est défini (en utilisant ENGINE_set_table_flags()), il n'y aura
       pas de tentatives d'initialisation, et la seule façon pour une table d'état de renvoyer à
       un ENGINE non NULL pour la requête « get_default » sera celle qui sera indiquée de façon
       explicite dans la table. Exemple : ENGINE_set_default_RSA() fait la même chose
       qu'ENGINE_register_RSA() sauf qu'elle définit aussi le cache de réponses de la table pour
       la requête « get_default ». Dans ce cas, les abstractions comme EVP_CIPHER, où les
       implémentations sont indexées par un « nid », ces drapeaux et réponses cachés sont
       différents des valeurs « nid ».

   Exigences de l'application
       Cette partie expliquera les choses de base qu'un programmeur d'applications doit connaître
       pour rendre disponibles les éléments les plus utiles de la fonctionnalité d'ENGINE à
       l'utilisateur. La première chose à considérer est si le programmeur veut fournir un module
       alternatif d'ENGINE disponible à l'application et à l'utilisateur. OpenSSL maintient une
       liste liée interne d'ENGINE « visibles » qu'il a besoin d'opérer — au démarrage, cette
       liste est vide et d'ailleurs si une application n'utilise pas d'appel de l'API d'ENGINE et
       qu'elle utilise un lien statique envers openssl, alors le binaire de l'application
       résultante ne contiendra aucun code d'ENGINE alternatif. La première considération est
       donc de savoir si toute implémentation d'ENGINE doit être rendue visible à OpenSSL — cela
       est contrôlé en appelant les différentes fonctions de « chargement », exemple :

        /* Rendre l'ENGINE S<« dynamique »> disponible */
        void ENGINE_load_dynamic(void);
        /* Rendre le support d'accélération matériel CryptoSwift disponible */
        void ENGINE_load_cswift(void);
        /* Rendre le support de matériel S<« CHIL »> de nCipher disponible */
        void ENGINE_load_chil(void);
        ...
        /* Rendre toutes les implémentations du paquet OpenSSL disponibles. */
        void ENGINE_load_builtin_engines(void);

       Après avoir appelé n'importe laquelle de ces fonctions, les objets ENGINE ont été alloués
       de façon dynamique, peuplés avec ces implémentations et liés à la liste chaînée interne
       d'OpenSSL. À partir de ce moment il est nécessaire de mentionner une fonction de l'API
       importante ;

        void ENGINE_cleanup(void);

       Si aucune fonction d'API ENGINE n'est appelée dans une application, alors il n'y a pas de
       fuite mémoire dont il faut s'inquiéter dans les fonctionnalités d'ENGINE ; néanmoins, si
       n'importe quel ENGINE est chargé, même s'il n'est jamais enregistré ou utilisé, il est
       nécessaire d'utiliser la fonction ENGINE_cleanup() pour le nettoyer de façon correcte
       avant la fermeture du programme, si l'utilisateur veut éviter les fuites mémoires. Ce
       mécanisme utilise une table enregistrant les rétroactions internes pour qu'une
       fonctionnalité d'API ENGINE, qui sait qu'elle a besoin d'être nettoyée, puisse enregistrer
       les détails du nettoyage à appeler pendant l'appel deENGINE_cleanup(). Cette approche
       permet à ENGINE_cleanup() de nettoyer après n'importe quelle utilisation par un programme
       d'une fonctionnalité d'ENGINE, mais cela ne crée pas de lien de dépendance à toutes les
       fonctionnalités possibles d'ENGINE — seules les rétroactions de nettoyage nécessaires aux
       fonctionnalités utilisées, seront requises par le lieur.

       Le fait que les ENGINES sont rendus visibles à OpenSSL (et de ce fait sont liés au
       programme et chargés en mémoire lors de l'exécution) ne veut pas dire qu'ils sont
       « enregistrés » ou appelés et utilisés par OpenSSL automatiquement — ce comportement est
       quelque chose qui doit être contrôlé par l'application. Certaines applications auront
       besoin d'autoriser l'utilisateur à spécifier exactement quel ENGINE il voudra utiliser si
       il y en a un qui doit être utilisé. D'autres préféreront tout charger pour que OpenSSL
       utilise automatiquement le premier ENGINE qui peut s'initialiser correctement
       — c'est-à-dire, qui puisse correspondre à une accélération matérielle attachée à la
       machine, ou quelque chose comme cela. Il y a probablement énormément d'autres façons par
       lesquelles l'application peut préférer gérer les choses, nous illustrerons donc simplement
       les conséquences telles qu'elles s'appliquent à des cas simples et laisserons les
       développeurs considérer ces cas et le code source de fonctions utilitaires d'OpenSSL comme
       guide.

       Utiliser une implémentation spécifique d'ENGINE

       Ici, nous allons supposer qu'une application a été configurée par son utilisateur ou
       administrateur pour utiliser l'ENGINE « ACME » s'il est disponible dans la version
       d'OpenSSL avec laquelle l'application a été compilée. S'il est disponible, il devra être
       utilisé par défaut pour tous les chiffrements RSA, DSA et les opérations par chiffrement
       symétrique, sinon OpenSSL devrait utiliser ses fonctionnalités internes comme d'habitude.
       Le code suivant illustre comment faire cela :

        ENGINE *e;
        const char *engine_id = "ACME";
        ENGINE_load_builtin_engines();
        e = ENGINE_by_id(engine_id);
        if(!e)
            /* le moteur n'est pas disponible */
            return;
        if(!ENGINE_init(e)) {
            /* le moteur n'a pas pu être initialisé, libérer « e » */
            ENGINE_free(e);
            return;
        }
        if(!ENGINE_set_default_RSA(e))
            /* Ceci devrait uniquement se produire quand S<« e »> ne peut être
             * initialisé, mais la déclaration précédente suggère qu'il l'a été. */
            abort();
        ENGINE_set_default_DSA(e);
        ENGINE_set_default_ciphers(e);
        /* Libère la référence fonctionnelle d'ENGINE_init() */
        ENGINE_finish(e);
        /* Libère la référence structurelle d'ENGINE_by_id() */
        ENGINE_free(e);

       Utiliser automatiquement les implémentations intégrées d'ENGINE

       Ici, nous allons supposer que l'on veut charger et enregistrer toutes les implémentations
       d'ENGINE fournies avec OpenSSL, de façon à ce que n'importe quel algorithme de
       cryptographie qui est utilisé par OpenSSL — s'il y a un ENGINE qui l'implémente et peut
       être initialisé — alors il sera utilisé. Le code suivant montre un exemple d'utilisation :

        /* Charger et rendre visible tous les paquets ENGINE dans la mémoire. */
        ENGINE_load_builtin_engines();
        /* Enregistrer tous les paquets pour tous les algorithmes qu'ils implémentent collectivement */
        ENGINE_register_all_complete();

       Cela est tout ce qui est requis. Par exemple, la prochaine fois qu'OpenSSL essaye de
       mettre en place une clé RSA, n'importe quel ENGINE fourni qui implémente RSA_METHOD sera
       passé à ENGINE_init() et si l'un d'entre eux réussit, cet ENGINE sera choisi par défaut
       pour l'utilisation de RSA.

   Support de configuration avancé
       Il y a un mécanisme géré par le framework de l'ENGINE qui autorise chaque implémentation
       d'ENGINE de définir un nombre arbitraire d'ensembles de « commandes » de configuration, de
       les révéler à OpenSSL et toute application basée sur OpenSSL. Ce mécanisme est entièrement
       basé sur l'utilisation de couple noms-valeurs et suppose que l'entrée est au format ASCII
       (pas d'unicode ou d'UTF pour l'instant !), c'est donc idéal si l'application veut fournir
       une possibilité de fournir, d'une façon transparente aux utilisateurs, des « directives »
       de configuration arbitraires directement à ces ENGINE. Il permet aussi à l'application de
       demander de façon dynamique à l'implémentation de l'ENGINE des noms, descriptions et
       drapeaux d'entrée des « commandes de contrôle » disponibles, ce qui fournit un programme
       plus flexible. Or, si l'utilisateur s'attend à connaitre quel ENGINE il utilise (dans le
       cas de matériel spécialisé, cela va sans dire) alors l'application peut ne pas
       s'intéresser à la découverte des commandes de contrôle gérées et plus simplement préférer
       passer des réglages directement à l'ENGINE tels qu'ils sont fournis par l'utilisateur.

       Avant d'illustrer les commandes de contrôle, il est raisonnable de mentionner ce pour quoi
       elles sont utilisées. De façon générale, il y a deux utilisations de commandes de
       contrôle ; la première consiste à fournir les détails nécessaires à l'implémentation (qui
       peut ne rien connaître du système hôte) pour que l'initialisation se fasse. Cela peut
       inclure n'importe quel chemin de pilote ou de fichier config qui doit être chargé, des
       adresses réseau requises, des identifiants de cartes à puce, des mots de passe pour
       initialiser des dispositifs sécurisés, des informations de connexion, etc. Cette classe de
       commandes a généralement besoin d'être passée à un ENGINE avant d'essayer de
       l'initialiser, c'est-à-dire avant d'appeler ENGINE_init(). L'autre classe de commande
       consiste en des réglages ou des opérations qui modifient certains comportements ou
       déclenchent la réalisation de certaines opérations, et ces commandes peuvent fonctionner
       avant ou après ENGINE_init(), ou dans certains cas avant et après. L'implémentation
       d'ENGINE doit fournir des indications de cela dans la description des commandes de
       contrôle intégrées et/ou dans la documentation externe finale.

       Envoyer des commandes de contrôle à un ENGINE

       Illustrons cela grâce à un exemple : une fonction pour laquelle l'appelant fournit le nom
       de l'ENGINE qu'il veut utiliser, une table de paires de chaînes de caractères à utiliser
       avant l'initialisation, et d'autres tables après l'initialisation. Notez que les paires de
       chaînes de caractères utilisées pour les commandes de contrôles consistent en un « nom »
       de commande suivit du « paramètre » de la commande — le paramètre pourrait être NULL dans
       certains cas mais le nom ne peut pas l'être. Cette fonction devrait initialiser l'ENGINE
       (en envoyant les « pré » commandes avant et les « post » commandes après) et le régler
       comme défaut pour tout sauf RAND, puis renvoyer un booléen pour un succès ou un échec.

        int generic_load_engine_fn(const char *engine_id,
                                   const char **pre_cmds, int pre_num,
                                   const char **post_cmds, int post_num)
        {
            ENGINE *e = ENGINE_by_id(engine_id);
            if(!e) return 0;
            while(pre_num--) {
                if(!ENGINE_ctrl_cmd_string(e, pre_cmds[0], pre_cmds[1], 0)) {
                    fprintf(stderr, "Failed command (%s - %s:%s)\n", engine_id,
                        pre_cmds[0], pre_cmds[1] ? S<pre_cmds[1] :> "(NULL)");
                    ENGINE_free(e);
                    return 0;
                }
                pre_cmds += 2;
            }
            if(!ENGINE_init(e)) {
                fprintf(stderr, "Failed initialisation\n");
                ENGINE_free(e);
                return 0;
            }
            /* ENGINE_init() a renvoyé une référence fonctionnelle, il faut donc libérer la référence structurelle d'ENGINE_by_id(). */
            ENGINE_free(e);
            while(post_num--) {
                if(!ENGINE_ctrl_cmd_string(e, post_cmds[0], post_cmds[1], 0)) {
                    fprintf(stderr, "Failed command (%s - %s:%s)\n", engine_id,
                        post_cmds[0], post_cmds[1] ? S<post_cmds[1] :> "(NULL)");
                    ENGINE_finish(e);
                    return 0;
                }
                post_cmds += 2;
            }
            ENGINE_set_default(e, ENGINE_METHOD_ALL & ~ENGINE_METHOD_RAND);
            /* Succès */
            return 1;
        }

       Notez qu'ENGINE_ctrl_cmd_string() accepte un argument booléen qui peut assouplir les
       sémantiques de la fonction — s'il est différent de 0, elle ne renverra un échec que si
       l'ENGINE prend en charge le nom de la commande mais a échoué lors de son exécution ; si
       l'ENGINE ne prend pas en charge le nom de la commande, elle renverra simplement succès
       sans rien faire. Dans ce cas, on suppose que l'utilisateur apporte des commandes
       spécifiques à l'ENGINE donné, on règle donc cela à FALSE.

       Découverte de commandes de contrôle gérées

       Il est possible de découvrir les noms, id numériques, descriptions et paramètres d'entrée
       des commandes de contrôle prises en charge par un ENGINE au moment de l'exécution en
       utilisant une référence structurelle. Notez que certaines commandes de contrôle définies
       dans OpenSSL intercepteront et géreront ces appels au nom d'ENGINE, c'est-à-dire le
       gestionnaire ctrl() d'ENGINE n'est pas utilisé pour les commandes de contrôle.
       openssl/engine.h définit un index, ENGINE_CMD_BASE, à partir duquel toutes les commandes
       de contrôle implémentées par ENGINE doivent être numérotées. Toute valeur de commande plus
       basse que ce symbole est considérée comme « générique » et est gérée directement par les
       routines noyau d'OpenSSL.

       C'est en utilisant ces contrôles « essentiels » que l'on peut découvrir les commandes de
       contrôle implémentées par un ENGINE donné, plus spécifiquement ces commandes :

        #define ENGINE_HAS_CTRL_FUNCTION               10
        #define ENGINE_CTRL_GET_FIRST_CMD_TYPE         11
        #define ENGINE_CTRL_GET_NEXT_CMD_TYPE          12
        #define ENGINE_CTRL_GET_CMD_FROM_NAME          13
        #define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD      14
        #define ENGINE_CTRL_GET_NAME_FROM_CMD          15
        #define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD      16
        #define ENGINE_CTRL_GET_DESC_FROM_CMD          17
        #define ENGINE_CTRL_GET_CMD_FLAGS              18

       Alors que ces commandes sont traitées de façon automatique par le code du framework
       d'OpenSSL, elles utilisent diverses propriétés exposées par chaque ENGINE pour traiter ces
       requêtes. Un ENGINE a 3 propriétés qu'il expose qui peuvent affecter comment celles-ci se
       comportent ; il peut fournir un contrôleur ctrl(), il peut spécifier
       ENGINE_FLAGS_MANUAL_CMD_CTRL dans les drapeaux de l'ENGINE, et il peut exposer un tableau
       de descriptions de commandes de contrôle. Si un ENGINE spécifie le drapeau
       ENGINE_FLAGS_MANUAL_CMD_CTRL, alors les commandes essentielles de contrôle seront
       simplement passées directement au gestionnaire ctrl() de l'ENGINE (et de ce fait, il doit
       y en avoir un de fourni), c'est donc le rôle de l'ENGINE de répondre à ces commandes
       « découvertes ». Si un drapeau n'est pas déterminé, alors le code du framework d'OpenSSL
       fonctionnera avec les règles suivantes :

        si aucun gestionnaire ctrl() n'est S<fourni ;>
            ENGINE_HAS_CTRL_FUNCTION renvoie FALSE (zero),
            toutes les autres commandes échouent.
        si un gestionnaire ctrl() a été fourni mais aucun tableau de commandes de contrôle n'a été S<fourni ;>
            ENGINE_HAS_CTRL_FUNCTION renvoie TRUE,
            toutes les autres commandes échouent.
        si un gestionnaire ctrl() et un tableau de commandes ont été S<fournis ;>
            ENGINE_HAS_CTRL_FUNCTION renvoie TRUE,
            toutes les autres commandes continuent leurs traitements ...

       Si le tableau de commandes de contrôle d'ENGINE est vide alors toutes les autres commandes
       échoueront, sinon ENGINE_CTRL_GET_FIRST_CMD_TYPE renvoie l'identifiant de la première
       commande prise en charge par l'ENGINE, ENGINE_GET_NEXT_CMD_TYPE prend l'identifiant d'une
       commande prise en charge par l'ENGINE et renvoie le prochain identifiant de commande, ou
       échoue s'il n'y en a plus, ENGINE_CMD_FROM_NAME prend un nom sous forme de chaîne de
       caractères pour une commande et renvoie l'identifiant correspondant ou échoue si la
       commande correspondante n'existe pas. Les commandes restantes prennent un identifiant de
       commande et renvoient les propriétés de la commande correspondante. Toutes, sauf
       ENGINE_CTRL_GET_FLAGS, renvoient la longueur de la chaîne de caractères du nom de la
       commande ou de la description, ou remplissent un tampon de caractères fourni avec la copie
       du nom ou de la description de la commande. ENGINE_CTRL_GET_FLAGS renvoie un masque OR bit
       à bit ayant les valeurs possibles suivantes :

        #define ENGINE_CMD_FLAG_NUMERIC                (unsigned int)0x0001
        #define ENGINE_CMD_FLAG_STRING                 (unsigned int)0x0002
        #define ENGINE_CMD_FLAG_NO_INPUT               (unsigned int)0x0004
        #define ENGINE_CMD_FLAG_INTERNAL               (unsigned int)0x0008

       Si le drapeau ENGINE_CMD_FLAG_INTERNAL est défini, alors n'importe quels autres drapeaux
       sont purement informationnels pour l'appelant — ce drapeau empêchera la commande d'être
       exécutée par les fonctions haut niveau d'un ENGINE comme ENGINE_ctrl_cmd_string(). Les
       commandes « INTERNES » ne sont pas supposées être exposées à des configurations basées sur
       du texte par les applications, administrations, utilisateurs, etc. Celles-ci peuvent gérer
       des opérations arbitraires à l’aide d'ENGINE_ctrl(), y compris le passage de ou vers les
       données des commandes de contrôle de n'importe quel type arbitraire. Ces commandes sont
       gérées dans le mécanisme de découverte pour simplement autoriser les applications à
       déterminer si un ENGINE gère certaines commandes spécifiques qu'il veut utiliser (par
       exemple : l'application « foo » veut faire une requête à différents ENGINE pour voir s'ils
       implémentent « FOO_GET_VENDOR_LOGO_GIF », et ENGINE peut de ce fait décider s'il prend en
       charge ou non cette extension spécifique à « foo »).

   Développements futurs
       L'API d'ENGINE et sa structure architecturale interne sont en cours de révision. Il est
       prévu d'avoir de nouvelles modifications dans la version 0.9.8 pour une prise en charge du
       chargement transparent d'ENGINE « dynamiques » (implémentés comme bibliothèques partagées
       autonomes). Cela devrait autoriser de fournir des implémentations ENGINE indépendamment
       des bibliothèques d'OpenSSL ou des applications basées sur OpenSSL, et supprimera aussi
       toute obligation pour les applications d'utiliser explicitement l'ENGINE « dynamique »
       pour se lier à des implémentations de bibliothèques partagées.

VOIR AUSSI

       rsa(3), dsa(3), dh(3), rand(3)

TRADUCTION

       La traduction de cette page de manuel est maintenue par les membres de la liste
       <debian-l10n-french AT lists DOT debian DOT org>. Veuillez signaler toute erreur de
       traduction par un rapport de bogue sur le paquet manpages-fr-extra.