⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 engine.pod

📁 openssl包含TLS
💻 POD
📖 第 1 页 / 共 2 页
字号:
 ENGINE_register_complete(X); ENGINE_set_default(Y, ENGINE_METHOD_ALL); e1 = ENGINE_get_default_RSA(); e2 = ENGINE_get_cipher_engine(A); e3 = ENGINE_get_cipher_engine(B); e4 = ENGINE_get_default_DSA(); e5 = ENGINE_get_cipher_engine(C);The results would be as follows; assert(e1 == X); assert(e2 == Y); assert(e3 == X); assert(e4 == Y); assert(e5 == NULL);=head2 Application requirementsThis section will explain the basic things an application programmer shouldsupport to make the most useful elements of the ENGINE functionalityavailable to the user. The first thing to consider is whether theprogrammer wishes to make alternative ENGINE modules available to theapplication and user. OpenSSL maintains an internal linked list of"visible" ENGINEs from which it has to operate - at start-up, this list isempty and in fact if an application does not call any ENGINE API calls andit uses static linking against openssl, then the resulting applicationbinary will not contain any alternative ENGINE code at all. So the firstconsideration is whether any/all available ENGINE implementations should bemade visible to OpenSSL - this is controlled by calling the various "load"functions, eg. /* Make the "dynamic" ENGINE available */ void ENGINE_load_dynamic(void); /* Make the CryptoSwift hardware acceleration support available */ void ENGINE_load_cswift(void); /* Make support for nCipher's "CHIL" hardware available */ void ENGINE_load_chil(void); ... /* Make ALL ENGINE implementations bundled with OpenSSL available */ void ENGINE_load_builtin_engines(void);Having called any of these functions, ENGINE objects would have beendynamically allocated and populated with these implementations and linkedinto OpenSSL's internal linked list. At this point it is important tomention an important API function; void ENGINE_cleanup(void);If no ENGINE API functions are called at all in an application, then thereare no inherent memory leaks to worry about from the ENGINE functionality,however if any ENGINEs are "load"ed, even if they are never registered orused, it is necessary to use the ENGINE_cleanup() function tocorrespondingly cleanup before program exit, if the caller wishes to avoidmemory leaks. This mechanism uses an internal callback registration tableso that any ENGINE API functionality that knows it requires cleanup canregister its cleanup details to be called during ENGINE_cleanup(). Thisapproach allows ENGINE_cleanup() to clean up after any ENGINE functionalityat all that your program uses, yet doesn't automatically create linkerdependencies to all possible ENGINE functionality - only the cleanupcallbacks required by the functionality you do use will be required by thelinker.The fact that ENGINEs are made visible to OpenSSL (and thus are linked intothe program and loaded into memory at run-time) does not mean they are"registered" or called into use by OpenSSL automatically - that behaviouris something for the application to have control over. Some applicationswill want to allow the user to specify exactly which ENGINE they want usedif any is to be used at all. Others may prefer to load all support and haveOpenSSL automatically use at run-time any ENGINE that is able tosuccessfully initialise - ie. to assume that this corresponds toacceleration hardware attached to the machine or some such thing. There areprobably numerous other ways in which applications may prefer to handlethings, so we will simply illustrate the consequences as they apply to acouple of simple cases and leave developers to consider these and thesource code to openssl's builtin utilities as guides.I<Using a specific ENGINE implementation>Here we'll assume an application has been configured by its user or adminto want to use the "ACME" ENGINE if it is available in the version ofOpenSSL the application was compiled with. If it is available, it should beused by default for all RSA, DSA, and symmetric cipher operation, otherwiseOpenSSL should use its builtin software as per usual. The following codeillustrates how to approach this; ENGINE *e; const char *engine_id = "ACME"; ENGINE_load_builtin_engines(); e = ENGINE_by_id(engine_id); if(!e)     /* the engine isn't available */     return; if(!ENGINE_init(e)) {     /* the engine couldn't initialise, release 'e' */     ENGINE_free(e);     return; } if(!ENGINE_set_default_RSA(e))     /* This should only happen when 'e' can't initialise, but the previous      * statement suggests it did. */     abort(); ENGINE_set_default_DSA(e); ENGINE_set_default_ciphers(e); /* Release the functional reference from ENGINE_init() */ ENGINE_finish(e); /* Release the structural reference from ENGINE_by_id() */ ENGINE_free(e);I<Automatically using builtin ENGINE implementations>Here we'll assume we want to load and register all ENGINE implementationsbundled with OpenSSL, such that for any cryptographic algorithm required byOpenSSL - if there is an ENGINE that implements it and can be initialise,it should be used. The following code illustrates how this can work; /* Load all bundled ENGINEs into memory and make them visible */ ENGINE_load_builtin_engines(); /* Register all of them for every algorithm they collectively implement */ ENGINE_register_all_complete();That's all that's required. Eg. the next time OpenSSL tries to set up anRSA key, any bundled ENGINEs that implement RSA_METHOD will be passed toENGINE_init() and if any of those succeed, that ENGINE will be set as thedefault for use with RSA from then on.=head2 Advanced configuration supportThere is a mechanism supported by the ENGINE framework that allows eachENGINE implementation to define an arbitrary set of configuration"commands" and expose them to OpenSSL and any applications based onOpenSSL. This mechanism is entirely based on the use of name-value pairsand and assumes ASCII input (no unicode or UTF for now!), so it is ideal ifapplications want to provide a transparent way for users to providearbitrary configuration "directives" directly to such ENGINEs. It is alsopossible for the application to dynamically interrogate the loaded ENGINEimplementations for the names, descriptions, and input flags of theiravailable "control commands", providing a more flexible configurationscheme. However, if the user is expected to know which ENGINE device he/sheis using (in the case of specialised hardware, this goes without saying)then applications may not need to concern themselves with discovering thesupported control commands and simply prefer to allow settings to passedinto ENGINEs exactly as they are provided by the user.Before illustrating how control commands work, it is worth mentioning whatthey are typically used for. Broadly speaking there are two uses forcontrol commands; the first is to provide the necessary details to theimplementation (which may know nothing at all specific to the host system)so that it can be initialised for use. This could include the path to anydriver or config files it needs to load, required network addresses,smart-card identifiers, passwords to initialise password-protected devices,logging information, etc etc. This class of commands typically needs to bepassed to an ENGINE B<before> attempting to initialise it, ie. beforecalling ENGINE_init(). The other class of commands consist of settings oroperations that tweak certain behaviour or cause certain operations to takeplace, and these commands may work either before or after ENGINE_init(), orin same cases both. ENGINE implementations should provide indications ofthis in the descriptions attached to builtin control commands and/or inexternal product documentation.I<Issuing control commands to an ENGINE>Let's illustrate by example; a function for which the caller supplies thename of the ENGINE it wishes to use, a table of string-pairs for use beforeinitialisation, and another table for use after initialisation. Note thatthe string-pairs used for control commands consist of a command "name"followed by the command "parameter" - the parameter could be NULL in somecases but the name can not. This function should initialise the ENGINE(issuing the "pre" commands beforehand and the "post" commands afterwards)and set it as the default for everything except RAND and then return aboolean success or failure. 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] ? 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() returned a functional reference, so free the structural      * reference from 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] ? post_cmds[1] : "(NULL)");             ENGINE_finish(e);             return 0;         }	 post_cmds += 2;     }     ENGINE_set_default(e, ENGINE_METHOD_ALL & ~ENGINE_METHOD_RAND);     /* Success */     return 1; }Note that ENGINE_ctrl_cmd_string() accepts a boolean argument that canrelax the semantics of the function - if set non-zero it will only returnfailure if the ENGINE supported the given command name but failed whileexecuting it, if the ENGINE doesn't support the command name it will simplyreturn success without doing anything. In this case we assume the user isonly supplying commands specific to the given ENGINE so we set this toFALSE.I<Discovering supported control commands>It is possible to discover at run-time the names, numerical-ids, descriptionsand input parameters of the control commands supported from a structuralreference to any ENGINE. It is first important to note that some controlcommands are defined by OpenSSL itself and it will intercept and handle thesecontrol commands on behalf of the ENGINE, ie. the ENGINE's ctrl() handler is notused for the control command. openssl/engine.h defines a symbol,ENGINE_CMD_BASE, that all control commands implemented by ENGINEs from. Anycommand value lower than this symbol is considered a "generic" command ishandled directly by the OpenSSL core routines.It is using these "core" control commands that one can discover the the controlcommands implemented by a given ENGINE, specifically the commands; #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		18Whilst these commands are automatically processed by the OpenSSL framework code,they use various properties exposed by each ENGINE by which to process thesequeries. An ENGINE has 3 properties it exposes that can affect this behaviour;it can supply a ctrl() handler, it can specify ENGINE_FLAGS_MANUAL_CMD_CTRL inthe ENGINE's flags, and it can expose an array of control command descriptions.If an ENGINE specifies the ENGINE_FLAGS_MANUAL_CMD_CTRL flag, then it willsimply pass all these "core" control commands directly to the ENGINE's ctrl()handler (and thus, it must have supplied one), so it is up to the ENGINE toreply to these "discovery" commands itself. If that flag is not set, then theOpenSSL framework code will work with the following rules; if no ctrl() handler supplied;     ENGINE_HAS_CTRL_FUNCTION returns FALSE (zero),     all other commands fail. if a ctrl() handler was supplied but no array of control commands;     ENGINE_HAS_CTRL_FUNCTION returns TRUE,     all other commands fail. if a ctrl() handler and array of control commands was supplied;     ENGINE_HAS_CTRL_FUNCTION returns TRUE,     all other commands proceed processing ...If the ENGINE's array of control commands is empty then all other commands willfail, otherwise; ENGINE_CTRL_GET_FIRST_CMD_TYPE returns the identifier ofthe first command supported by the ENGINE, ENGINE_GET_NEXT_CMD_TYPE takes theidentifier of a command supported by the ENGINE and returns the next commandidentifier or fails if there are no more, ENGINE_CMD_FROM_NAME takes a stringname for a command and returns the corresponding identifier or fails if no suchcommand name exists, and the remaining commands take a command identifier andreturn properties of the corresponding commands. All exceptENGINE_CTRL_GET_FLAGS return the string length of a command name or description,or populate a supplied character buffer with a copy of the command name ordescription. ENGINE_CTRL_GET_FLAGS returns a bitwise-OR'd mask of the followingpossible values; #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)0x0008If the ENGINE_CMD_FLAG_INTERNAL flag is set, then any other flags are purelyinformational to the caller - this flag will prevent the command being usablefor any higher-level ENGINE functions such as ENGINE_ctrl_cmd_string()."INTERNAL" commands are not intended to be exposed to text-based configurationby applications, administrations, users, etc. These can support arbitraryoperations via ENGINE_ctrl(), including passing to and/or from the controlcommands data of any arbitrary type. These commands are supported in thediscovery mechanisms simply to allow applications determinie if an ENGINEsupports certain specific commands it might want to use (eg. application "foo"might query various ENGINEs to see if they implement "FOO_GET_VENDOR_LOGO_GIF" -and ENGINE could therefore decide whether or not to support this "foo"-specificextension).=head2 Future developmentsThe ENGINE API and internal architecture is currently being reviewed. Slated forpossible release in 0.9.8 is support for transparent loading of "dynamic"ENGINEs (built as self-contained shared-libraries). This would allow ENGINEimplementations to be provided independantly of OpenSSL libraries and/orOpenSSL-based applications, and would also remove any requirement forapplications to explicitly use the "dynamic" ENGINE to bind to shared-libraryimplementations.=head1 SEE ALSOL<rsa(3)|rsa(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, L<rand(3)|rand(3)>,L<RSA_new_method(3)|RSA_new_method(3)>=cut

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -