.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "fr::crypto::engine 3SSL" .TH fr::crypto::engine 3SSL "2015-12-31" "1.0.2a 1.0.2c" "OpenSSL" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NOM" .IX Header "NOM" moteur \- \s-1ENGINE\s0 module de support cryptographique .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& #include \& \& 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); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Ces fonctions créent, manipulent et utilisent des modules cryptographiques sous la forme d'objets \fB\s-1ENGINE\s0\fR. 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. .PP La fonctionnalité cryptographique qui peut être fournie par l'implémentation d'un \fB\s-1ENGINE\s0\fR inclut les abstractions suivantes : .PP .Vb 6 \& RSA_METHOD \- pour fournir une implémentation RSA alternative \& DSA_METHOD, DH_METHOD, RAND_METHOD, ECDH_METHOD, ECDSA_METHOD, \& STORE_METHOD \- identique pour d\*(Aqautres API d\*(AqOpenSSL \& EVP_CIPHER \- potentiellement plusieurs algorithmes de chiffrement (indexé par \*(Aqnid\*(Aq) \& EVP_DIGEST \- potentiellement plusieurs algorithmes de hachage (indexé par \*(Aqnid\*(Aq) \& key\-loading \- chargement des clés EVP_PKEY publiques/privées .Ve .SS "Référence de calculs et traitements" .IX Subsection "Référence de calculs et traitements" À cause de la nature modulaire de l'\s-1API ENGINE,\s0 les pointeurs vers les \&\s-1ENGINE\s0 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 \s-1ENGINE\s0 sous-jacent. C'est\-à\-dire que l'on doit obtenir une nouvelle référence lors de la copie d'un pointeur vers un \&\s-1ENGINE\s0 si la copie doit être utilisée (et libérée) de façon indépendante. .PP Les objets \s-1ENGINE\s0 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 \s-1ENGINE\s0 est intrinsèquement une référence \fBstructurelle\fR \- 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. .PP Mais, une référence structurelle n'offre aucune garantie que l'\s-1ENGINE\s0 soit initialisé et capable d'utiliser n'importe laquelle de ses implémentations cryptographiques. En effet, il est fort probable que la plupart des \s-1ENGINE\s0 ne puissent pas s'initialiser dans des environnements typiques, car les \&\s-1ENGINES\s0 sont généralement utilisés pour gérer du matériel spécialisé. Pour utiliser une fonctionnalité d'\s-1ENGINE,\s0 il est nécessaire d'avoir une référence \fBfonctionnelle\fR. 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 \s-1ENGINE,\s0 il est garanti que cet \s-1ENGINE\s0 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. .PP \&\fIStructural references\fR .PP Ce type de référence de base est utilisé pour instancier de nouveaux \s-1ENGINE,\s0 itérer sur les listes liées d'\s-1ENGINE\s0 chargés d'OpenSSL, lire les informations d'un \s-1ENGINE,\s0 etc. Une référence structurelle est essentiellement suffisante pour des requêtes ou pour manipuler les données d'implémentation d'un \s-1ENGINE\s0 au lieu d'utiliser ses fonctionnalités. .PP La fonction \fIENGINE_new()\fR renvoie une référence structurelle vers un objet \&\s-1ENGINE\s0 vide. Il y a d'autres fonctions d'\s-1API\s0 dans \s-1ENGINE\s0 qui renvoient une référence structurelle comme : \fIENGINE_by_id()\fR, \fIENGINE_get_first()\fR, \&\fIENGINE_get_last()\fR, \fIENGINE_get_next()\fR, \fIENGINE_get_prev()\fR. Toute référence structurelle devrait être libérée par un appel correspondant à la fonction \&\fIENGINE_free()\fR — l'objet \s-1ENGINE\s0 lui\-même ne sera nettoyé et désalloué que lorsque la dernière référence structurelle sera libérée. .PP On doit aussi remarquer que beaucoup d'appels de fonctions d'\s-1API\s0 d'\s-1ENGINE\s0 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'\s-1ENGINE\s0 sera nécessaire à OpenSSL après le retour de la fonction. Exemple : la fonction d'ajout d'un nouvel \s-1ENGINE\s0 à la liste interne d'OpenSSL est \fBENGINE_add\fR() — 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 \fIENGINE_free()\fR 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 \fBENGINE_get_next\fR() et \fBENGINE_get_prev\fR() sont utilisées pour itérer à travers la liste interne d'\s-1ENGINE\s0 — elles renverront une nouvelle référence structurelle au prochain (ou précédent) \s-1ENGINE\s0 dans la liste ou \s-1NULL\s0 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. .PP 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. .PP \&\fIRéférences fonctionnelles\fR .PP Comme mentionné, les références fonctionnelles existent lorsque la fonctionnalité cryptographique d'un \s-1ENGINE\s0 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'\s-1ENGINE,\s0 ou en demandant à l'\s-1ENGINE\s0 par défaut d'OpenSSL pour une tâche cryptographique donnée. .PP Pour obtenir une référence fonctionnelle à partir d'une référence structurelle, appelez la fonction \fIENGINE_init()\fR. Cela renvoie 0 si l'\s-1ENGINE\s0 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'\s-1ENGINE\s0 est maintenant opérationnel et a alloué une référence \&\fBfonctionnelle\fR à l'\s-1ENGINE.\s0 Toutes les références fonctionnelles sont libérées en appelant \fIENGINE_finish()\fR (ce qui supprime les références structurelles implicites aussi). .PP 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 \&\fIENGINE_get_default_RSA()\fR, \fIENGINE_get_default_cipher_engine()\fR, 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 \s-1RSA, DSA, EVP_CIPHER_CTX,\s0 etc. .SS "Implémentations par défaut" .IX Subsection "Implémentations par défaut" Pour chaque abstraction gérée, le code d'\s-1ENGINE\s0 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 \s-1EVP_CIPHER\s0 et \s-1EVP_DIGEST\s0 gèrent énormément d'algorithmes et de modes distincts, et les \s-1ENGINE\s0 peuvent arbitrairement tous les prendre en charge. Dans le cas d'autres abstractions comme \s-1RSA, DSA,\s0 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 ». .PP Quand une requête d'un \s-1ENGINE\s0 par défaut pour une abstraction/algorithme/mode est faite (par ex. en appelant RSA_new_method(\s-1NULL\s0)), un appel « get_default » peut être fait au sous\-système de l'\s-1ENGINE\s0 pour traiter l'état de la table correspondante et renvoyer une référence fonctionnelle vers un \s-1ENGINE\s0 initialisé dont l'implémentation devrait être utilisée. Si aucun \s-1ENGINE\s0 ne doit (ou ne peut) être utilisé, elle renverra \s-1NULL\s0 et l'appelant opérera avec un identificateur d'\s-1ENGINE NULL\s0 — 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'\s-1API ENGINE\s0 n'existe. .PP 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 \s-1ENGINE\s0 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 \s-1ENGINE,\s0 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 \s-1NULL\s0 si aucun \s-1ENGINE\s0 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 \s-1ENGINE_TABLE_FLAG_NOINIT\s0 est défini (en utilisant \fIENGINE_set_table_flags()\fR), il n'y aura pas de tentatives d'initialisation, et la seule façon pour une table d'état de renvoyer à un \&\s-1ENGINE\s0 non \s-1NULL\s0 pour la requête « get_default » sera celle qui sera indiquée de façon explicite dans la table. Exemple : \fIENGINE_set_default_RSA()\fR fait la même chose qu'\fIENGINE_register_RSA()\fR 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 \s-1EVP_CIPHER,\s0 où les implémentations sont indexées par un « nid », ces drapeaux et réponses cachés sont différents des valeurs « nid ». .SS "Exigences de l'application" .IX Subsection "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'\s-1ENGINE\s0 à l'utilisateur. La première chose à considérer est si le programmeur veut fournir un module alternatif d'\s-1ENGINE\s0 disponible à l'application et à l'utilisateur. OpenSSL maintient une liste liée interne d'\s-1ENGINE\s0 « 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'\s-1API\s0 d'\s-1ENGINE\s0 et qu'elle utilise un lien statique envers openssl, alors le binaire de l'application résultante ne contiendra aucun code d'\s-1ENGINE\s0 alternatif. La première considération est donc de savoir si toute implémentation d'\s-1ENGINE\s0 doit être rendue visible à OpenSSL — cela est contrôlé en appelant les différentes fonctions de « chargement », exemple : .PP .Vb 9 \& /* Rendre l\*(AqENGINE S<« dynamique »> disponible */ \& void ENGINE_load_dynamic(void); \& /* Rendre le support d\*(Aqaccé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); .Ve .PP Après avoir appelé n'importe laquelle de ces fonctions, les objets \s-1ENGINE\s0 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'\s-1API\s0 importante ; .PP .Vb 1 \& void ENGINE_cleanup(void); .Ve .PP Si aucune fonction d'\s-1API ENGINE\s0 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'\s-1ENGINE \s0; néanmoins, si n'importe quel \s-1ENGINE\s0 est chargé, même s'il n'est jamais enregistré ou utilisé, il est nécessaire d'utiliser la fonction \&\fIENGINE_cleanup()\fR 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'\s-1API ENGINE,\s0 qui sait qu'elle a besoin d'être nettoyée, puisse enregistrer les détails du nettoyage à appeler pendant l'appel \&\fIdeENGINE_cleanup()\fR. Cette approche permet à \fIENGINE_cleanup()\fR de nettoyer après n'importe quelle utilisation par un programme d'une fonctionnalité d'\s-1ENGINE,\s0 mais cela ne crée pas de lien de dépendance à toutes les fonctionnalités possibles d'\s-1ENGINE\s0 — seules les rétroactions de nettoyage nécessaires aux fonctionnalités utilisées, seront requises par le lieur. .PP Le fait que les \s-1ENGINES\s0 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 \s-1ENGINE\s0 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 \s-1ENGINE\s0 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. .PP \&\fIUtiliser une implémentation spécifique d'\s-1ENGINE\s0\fR .PP Ici, nous allons supposer qu'une application a été configurée par son utilisateur ou administrateur pour utiliser l'\s-1ENGINE\s0 « \s-1ACME\s0 » 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 \s-1RSA, DSA\s0 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 : .PP .Vb 10 \& ENGINE *e; \& const char *engine_id = "ACME"; \& ENGINE_load_builtin_engines(); \& e = ENGINE_by_id(engine_id); \& if(!e) \& /* le moteur n\*(Aqest pas disponible */ \& return; \& if(!ENGINE_init(e)) { \& /* le moteur n\*(Aqa 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\*(Aqil l\*(Aqa été. */ \& abort(); \& ENGINE_set_default_DSA(e); \& ENGINE_set_default_ciphers(e); \& /* Libère la référence fonctionnelle d\*(AqENGINE_init() */ \& ENGINE_finish(e); \& /* Libère la référence structurelle d\*(AqENGINE_by_id() */ \& ENGINE_free(e); .Ve .PP \&\fIUtiliser automatiquement les implémentations intégrées d'\s-1ENGINE\s0\fR .PP Ici, nous allons supposer que l'on veut charger et enregistrer toutes les implémentations d'\s-1ENGINE\s0 fournies avec OpenSSL, de façon à ce que n'importe quel algorithme de cryptographie qui est utilisé par OpenSSL — s'il y a un \&\s-1ENGINE\s0 qui l'implémente et peut être initialisé — alors il sera utilisé. Le code suivant montre un exemple d'utilisation : .PP .Vb 4 \& /* 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\*(Aqils implémentent collectivement */ \& ENGINE_register_all_complete(); .Ve .PP Cela est tout ce qui est requis. Par exemple, la prochaine fois qu'OpenSSL essaye de mettre en place une clé \s-1RSA,\s0 n'importe quel \s-1ENGINE\s0 fourni qui implémente \s-1RSA_METHOD\s0 sera passé à \fIENGINE_init()\fR et si l'un d'entre eux réussit, cet \s-1ENGINE\s0 sera choisi par défaut pour l'utilisation de \s-1RSA.\s0 .SS "Support de configuration avancé" .IX Subsection "Support de configuration avancé" Il y a un mécanisme géré par le framework de l'\s-1ENGINE\s0 qui autorise chaque implémentation d'\s-1ENGINE\s0 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 \&\s-1ASCII \s0(pas d'unicode ou d'\s-1UTF\s0 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 \s-1ENGINE.\s0 Il permet aussi à l'application de demander de façon dynamique à l'implémentation de l'\s-1ENGINE\s0 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 \s-1ENGINE\s0 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'\s-1ENGINE\s0 tels qu'ils sont fournis par l'utilisateur. .PP 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 \s-1ENGINE \s0\fBavant\fR d'essayer de l'initialiser, c'est\-à\-dire avant d'appeler \fIENGINE_init()\fR. 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 \fIENGINE_init()\fR, ou dans certains cas avant et après. L'implémentation d'\s-1ENGINE\s0 doit fournir des indications de cela dans la description des commandes de contrôle intégrées et/ou dans la documentation externe finale. .PP \&\fIEnvoyer des commandes de contrôle à un \s-1ENGINE\s0\fR .PP Illustrons cela grâce à un exemple : une fonction pour laquelle l'appelant fournit le nom de l'\s-1ENGINE\s0 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 \&\s-1NULL\s0 dans certains cas mais le nom ne peut pas l'être. Cette fonction devrait initialiser l'\s-1ENGINE \s0(en envoyant les « pré » commandes avant et les « post » commandes après) et le régler comme défaut pour tout sauf \s-1RAND,\s0 puis renvoyer un booléen pour un succès ou un échec. .PP .Vb 10 \& 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)\en", engine_id, \& pre_cmds[0], pre_cmds[1] ? S "(NULL)"); \& ENGINE_free(e); \& return 0; \& } \& pre_cmds += 2; \& } \& if(!ENGINE_init(e)) { \& fprintf(stderr, "Failed initialisation\en"); \& 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\*(AqENGINE_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)\en", engine_id, \& post_cmds[0], post_cmds[1] ? S "(NULL)"); \& ENGINE_finish(e); \& return 0; \& } \& post_cmds += 2; \& } \& ENGINE_set_default(e, ENGINE_METHOD_ALL & ~ENGINE_METHOD_RAND); \& /* Succès */ \& return 1; \& } .Ve .PP Notez qu'\fIENGINE_ctrl_cmd_string()\fR 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'\s-1ENGINE\s0 prend en charge le nom de la commande mais a échoué lors de son exécution ; si l'\s-1ENGINE\s0 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'\s-1ENGINE\s0 donné, on règle donc cela à \s-1FALSE.\s0 .PP \&\fIDécouverte de commandes de contrôle gérées\fR .PP 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 \s-1ENGINE\s0 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'\s-1ENGINE,\s0 c'est\-à\-dire le gestionnaire \fIctrl()\fR d'\s-1ENGINE\s0 n'est pas utilisé pour les commandes de contrôle. openssl/engine.h définit un index, \s-1ENGINE_CMD_BASE,\s0 à partir duquel toutes les commandes de contrôle implémentées par \s-1ENGINE\s0 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. .PP C'est en utilisant ces contrôles « essentiels » que l'on peut découvrir les commandes de contrôle implémentées par un \s-1ENGINE\s0 donné, plus spécifiquement ces commandes : .PP .Vb 9 \& #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 .Ve .PP 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 \&\s-1ENGINE\s0 pour traiter ces requêtes. Un \s-1ENGINE\s0 a 3 propriétés qu'il expose qui peuvent affecter comment celles-ci se comportent ; il peut fournir un contrôleur \fIctrl()\fR, il peut spécifier \s-1ENGINE_FLAGS_MANUAL_CMD_CTRL\s0 dans les drapeaux de l'\s-1ENGINE,\s0 et il peut exposer un tableau de descriptions de commandes de contrôle. Si un \s-1ENGINE\s0 spécifie le drapeau \&\s-1ENGINE_FLAGS_MANUAL_CMD_CTRL,\s0 alors les commandes essentielles de contrôle seront simplement passées directement au gestionnaire \fIctrl()\fR de l'\s-1ENGINE \s0(et de ce fait, il doit y en avoir un de fourni), c'est donc le rôle de l'\s-1ENGINE\s0 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 : .PP .Vb 9 \& si aucun gestionnaire ctrl() n\*(Aqest S \& 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\*(Aqa été S \& ENGINE_HAS_CTRL_FUNCTION renvoie TRUE, \& toutes les autres commandes échouent. \& si un gestionnaire ctrl() et un tableau de commandes ont été S \& ENGINE_HAS_CTRL_FUNCTION renvoie TRUE, \& toutes les autres commandes continuent leurs traitements ... .Ve .PP Si le tableau de commandes de contrôle d'\s-1ENGINE\s0 est vide alors toutes les autres commandes échoueront, sinon \s-1ENGINE_CTRL_GET_FIRST_CMD_TYPE\s0 renvoie l'identifiant de la première commande prise en charge par l'\s-1ENGINE, ENGINE_GET_NEXT_CMD_TYPE\s0 prend l'identifiant d'une commande prise en charge par l'\s-1ENGINE\s0 et renvoie le prochain identifiant de commande, ou échoue s'il n'y en a plus, \s-1ENGINE_CMD_FROM_NAME\s0 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 \s-1ENGINE_CTRL_GET_FLAGS,\s0 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. \s-1ENGINE_CTRL_GET_FLAGS\s0 renvoie un masque \s-1OR\s0 bit à bit ayant les valeurs possibles suivantes : .PP .Vb 4 \& #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 .Ve .PP Si le drapeau \s-1ENGINE_CMD_FLAG_INTERNAL\s0 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 \&\s-1ENGINE\s0 comme \fIENGINE_ctrl_cmd_string()\fR. Les commandes « \s-1INTERNES\s0 » 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'\fIENGINE_ctrl()\fR, 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 \s-1ENGINE\s0 gère certaines commandes spécifiques qu'il veut utiliser (par exemple : l'application « foo » veut faire une requête à différents \s-1ENGINE\s0 pour voir s'ils implémentent « \s-1FOO_GET_VENDOR_LOGO_GIF\s0 », et \s-1ENGINE\s0 peut de ce fait décider s'il prend en charge ou non cette extension spécifique à « foo »). .SS "Développements futurs" .IX Subsection "Développements futurs" L'\s-1API\s0 d'\s-1ENGINE\s0 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'\s-1ENGINE\s0 « dynamiques » (implémentés comme bibliothèques partagées autonomes). Cela devrait autoriser de fournir des implémentations \s-1ENGINE\s0 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'\s-1ENGINE\s0 « dynamique » pour se lier à des implémentations de bibliothèques partagées. .SH "VOIR AUSSI" .IX Header "VOIR AUSSI" \&\fIrsa\fR\|(3), \fIdsa\fR\|(3), \fIdh\fR\|(3), \fIrand\fR\|(3) .SH "TRADUCTION" .IX Header "TRADUCTION" La traduction de cette page de manuel est maintenue par les membres de la liste . Veuillez signaler toute erreur de traduction par un rapport de bogue sur le paquet manpages-fr-extra.