123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742 |
- .\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35)
- .\"
- .\" 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 >0, 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
- ..
- .if !\nF .nr F 0
- .if \nF>0 \{\
- . de IX
- . tm Index:\\$1\t\\n%\t"\\$2"
- ..
- . if !\nF==2 \{\
- . nr % 0
- . nr F 2
- . \}
- .\}
- .\"
- .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
- .\" Fear. Run. Save yourself. No user-serviceable parts.
- . \" fudge factors for nroff and troff
- .if n \{\
- . ds #H 0
- . ds #V .8m
- . ds #F .3m
- . ds #[ \f1
- . ds #] \fP
- .\}
- .if t \{\
- . ds #H ((1u-(\\\\n(.fu%2u))*.13m)
- . ds #V .6m
- . ds #F 0
- . ds #[ \&
- . ds #] \&
- .\}
- . \" simple accents for nroff and troff
- .if n \{\
- . ds ' \&
- . ds ` \&
- . ds ^ \&
- . ds , \&
- . ds ~ ~
- . ds /
- .\}
- .if t \{\
- . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
- . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
- . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
- . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
- . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
- . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
- .\}
- . \" troff and (daisy-wheel) nroff accents
- .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
- .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
- .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
- .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
- .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
- .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
- .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
- .ds ae a\h'-(\w'a'u*4/10)'e
- .ds Ae A\h'-(\w'A'u*4/10)'E
- . \" corrections for vroff
- .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
- .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
- . \" for low resolution devices (crt and lpr)
- .if \n(.H>23 .if \n(.V>19 \
- \{\
- . ds : e
- . ds 8 ss
- . ds o a
- . ds d- d\h'-1'\(ga
- . ds D- D\h'-1'\(hy
- . ds th \o'bp'
- . ds Th \o'LP'
- . ds ae ae
- . ds Ae AE
- .\}
- .rm #[ #] #H #V #F C
- .\" ========================================================================
- .\"
- .IX Title "engine 3"
- .TH engine 3 "2019-09-12" "1.0.2g" "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 "NAME"
- engine \- ENGINE cryptographic module support
- .SH "SYNOPSIS"
- .IX Header "SYNOPSIS"
- .Vb 1
- \& #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);
- .Ve
- .SH "DESCRIPTION"
- .IX Header "DESCRIPTION"
- These functions create, manipulate, and use cryptographic modules in the
- form of \fB\s-1ENGINE\s0\fR objects. These objects act as containers for
- implementations of cryptographic algorithms, and support a
- reference-counted mechanism to allow them to be dynamically loaded in and
- out of the running application.
- .PP
- The cryptographic functionality that can be provided by an \fB\s-1ENGINE\s0\fR
- implementation includes the following abstractions;
- .PP
- .Vb 6
- \& RSA_METHOD \- for providing alternative RSA implementations
- \& DSA_METHOD, DH_METHOD, RAND_METHOD, ECDH_METHOD, ECDSA_METHOD,
- \& STORE_METHOD \- similarly for other OpenSSL APIs
- \& EVP_CIPHER \- potentially multiple cipher algorithms (indexed by \*(Aqnid\*(Aq)
- \& EVP_DIGEST \- potentially multiple hash algorithms (indexed by \*(Aqnid\*(Aq)
- \& key\-loading \- loading public and/or private EVP_PKEY keys
- .Ve
- .SS "Reference counting and handles"
- .IX Subsection "Reference counting and handles"
- Due to the modular nature of the \s-1ENGINE API,\s0 pointers to ENGINEs need to be
- treated as handles \- ie. not only as pointers, but also as references to
- the underlying \s-1ENGINE\s0 object. Ie. one should obtain a new reference when
- making copies of an \s-1ENGINE\s0 pointer if the copies will be used (and
- released) independently.
- .PP
- \&\s-1ENGINE\s0 objects have two levels of reference-counting to match the way in
- which the objects are used. At the most basic level, each \s-1ENGINE\s0 pointer is
- inherently a \fBstructural\fR reference \- a structural reference is required
- to use the pointer value at all, as this kind of reference is a guarantee
- that the structure can not be deallocated until the reference is released.
- .PP
- However, a structural reference provides no guarantee that the \s-1ENGINE\s0 is
- initialised and able to use any of its cryptographic
- implementations. Indeed it's quite possible that most ENGINEs will not
- initialise at all in typical environments, as ENGINEs are typically used to
- support specialised hardware. To use an \s-1ENGINE\s0's functionality, you need a
- \&\fBfunctional\fR reference. This kind of reference can be considered a
- specialised form of structural reference, because each functional reference
- implicitly contains a structural reference as well \- however to avoid
- difficult-to-find programming bugs, it is recommended to treat the two
- kinds of reference independently. If you have a functional reference to an
- \&\s-1ENGINE,\s0 you have a guarantee that the \s-1ENGINE\s0 has been initialised and
- is ready to perform cryptographic operations, and will remain initialised
- until after you have released your reference.
- .PP
- \&\fIStructural references\fR
- .PP
- This basic type of reference is used for instantiating new ENGINEs,
- iterating across OpenSSL's internal linked-list of loaded
- ENGINEs, reading information about an \s-1ENGINE,\s0 etc. Essentially a structural
- reference is sufficient if you only need to query or manipulate the data of
- an \s-1ENGINE\s0 implementation rather than use its functionality.
- .PP
- The \fIENGINE_new()\fR function returns a structural reference to a new (empty)
- \&\s-1ENGINE\s0 object. There are other \s-1ENGINE API\s0 functions that return structural
- references such as; \fIENGINE_by_id()\fR, \fIENGINE_get_first()\fR, \fIENGINE_get_last()\fR,
- \&\fIENGINE_get_next()\fR, \fIENGINE_get_prev()\fR. All structural references should be
- released by a corresponding to call to the \fIENGINE_free()\fR function \- the
- \&\s-1ENGINE\s0 object itself will only actually be cleaned up and deallocated when
- the last structural reference is released.
- .PP
- It should also be noted that many \s-1ENGINE API\s0 function calls that accept a
- structural reference will internally obtain another reference \- typically
- this happens whenever the supplied \s-1ENGINE\s0 will be needed by OpenSSL after
- the function has returned. Eg. the function to add a new \s-1ENGINE\s0 to
- OpenSSL's internal list is \fIENGINE_add()\fR \- if this function returns success,
- then OpenSSL will have stored a new structural reference internally so the
- caller is still responsible for freeing their own reference with
- \&\fIENGINE_free()\fR when they are finished with it. In a similar way, some
- functions will automatically release the structural reference passed to it
- if part of the function's job is to do so. Eg. the \fIENGINE_get_next()\fR and
- \&\fIENGINE_get_prev()\fR functions are used for iterating across the internal
- \&\s-1ENGINE\s0 list \- they will return a new structural reference to the next (or
- previous) \s-1ENGINE\s0 in the list or \s-1NULL\s0 if at the end (or beginning) of the
- list, but in either case the structural reference passed to the function is
- released on behalf of the caller.
- .PP
- To clarify a particular function's handling of references, one should
- always consult that function's documentation \*(L"man\*(R" page, or failing that
- the openssl/engine.h header file includes some hints.
- .PP
- \&\fIFunctional references\fR
- .PP
- As mentioned, functional references exist when the cryptographic
- functionality of an \s-1ENGINE\s0 is required to be available. A functional
- reference can be obtained in one of two ways; from an existing structural
- reference to the required \s-1ENGINE,\s0 or by asking OpenSSL for the default
- operational \s-1ENGINE\s0 for a given cryptographic purpose.
- .PP
- To obtain a functional reference from an existing structural reference,
- call the \fIENGINE_init()\fR function. This returns zero if the \s-1ENGINE\s0 was not
- already operational and couldn't be successfully initialised (eg. lack of
- system drivers, no special hardware attached, etc), otherwise it will
- return non-zero to indicate that the \s-1ENGINE\s0 is now operational and will
- have allocated a new \fBfunctional\fR reference to the \s-1ENGINE.\s0 All functional
- references are released by calling \fIENGINE_finish()\fR (which removes the
- implicit structural reference as well).
- .PP
- The second way to get a functional reference is by asking OpenSSL for a
- default implementation for a given task, eg. by \fIENGINE_get_default_RSA()\fR,
- \&\fIENGINE_get_default_cipher_engine()\fR, etc. These are discussed in the next
- section, though they are not usually required by application programmers as
- they are used automatically when creating and using the relevant
- algorithm-specific types in OpenSSL, such as \s-1RSA, DSA, EVP_CIPHER_CTX,\s0 etc.
- .SS "Default implementations"
- .IX Subsection "Default implementations"
- For each supported abstraction, the \s-1ENGINE\s0 code maintains an internal table
- of state to control which implementations are available for a given
- abstraction and which should be used by default. These implementations are
- registered in the tables and indexed by an 'nid' value, because
- abstractions like \s-1EVP_CIPHER\s0 and \s-1EVP_DIGEST\s0 support many distinct
- algorithms and modes, and ENGINEs can support arbitrarily many of them.
- In the case of other abstractions like \s-1RSA, DSA,\s0 etc, there is only one
- \&\*(L"algorithm\*(R" so all implementations implicitly register using the same 'nid'
- index.
- .PP
- When a default \s-1ENGINE\s0 is requested for a given abstraction/algorithm/mode, (eg.
- when calling RSA_new_method(\s-1NULL\s0)), a \*(L"get_default\*(R" call will be made to the
- \&\s-1ENGINE\s0 subsystem to process the corresponding state table and return a
- functional reference to an initialised \s-1ENGINE\s0 whose implementation should be
- used. If no \s-1ENGINE\s0 should (or can) be used, it will return \s-1NULL\s0 and the caller
- will operate with a \s-1NULL ENGINE\s0 handle \- this usually equates to using the
- conventional software implementation. In the latter case, OpenSSL will from
- then on behave the way it used to before the \s-1ENGINE API\s0 existed.
- .PP
- Each state table has a flag to note whether it has processed this
- \&\*(L"get_default\*(R" query since the table was last modified, because to process
- this question it must iterate across all the registered ENGINEs in the
- table trying to initialise each of them in turn, in case one of them is
- operational. If it returns a functional reference to an \s-1ENGINE,\s0 it will
- also cache another reference to speed up processing future queries (without
- needing to iterate across the table). Likewise, it will cache a \s-1NULL\s0
- response if no \s-1ENGINE\s0 was available so that future queries won't repeat the
- same iteration unless the state table changes. This behaviour can also be
- changed; if the \s-1ENGINE_TABLE_FLAG_NOINIT\s0 flag is set (using
- \&\fIENGINE_set_table_flags()\fR), no attempted initialisations will take place,
- instead the only way for the state table to return a non-NULL \s-1ENGINE\s0 to the
- \&\*(L"get_default\*(R" query will be if one is expressly set in the table. Eg.
- \&\fIENGINE_set_default_RSA()\fR does the same job as \fIENGINE_register_RSA()\fR except
- that it also sets the state table's cached response for the \*(L"get_default\*(R"
- query. In the case of abstractions like \s-1EVP_CIPHER,\s0 where implementations are
- indexed by 'nid', these flags and cached-responses are distinct for each 'nid'
- value.
- .SS "Application requirements"
- .IX Subsection "Application requirements"
- This section will explain the basic things an application programmer should
- support to make the most useful elements of the \s-1ENGINE\s0 functionality
- available to the user. The first thing to consider is whether the
- programmer wishes to make alternative \s-1ENGINE\s0 modules available to the
- application and user. OpenSSL maintains an internal linked list of
- \&\*(L"visible\*(R" ENGINEs from which it has to operate \- at start-up, this list is
- empty and in fact if an application does not call any \s-1ENGINE API\s0 calls and
- it uses static linking against openssl, then the resulting application
- binary will not contain any alternative \s-1ENGINE\s0 code at all. So the first
- consideration is whether any/all available \s-1ENGINE\s0 implementations should be
- made visible to OpenSSL \- this is controlled by calling the various \*(L"load\*(R"
- functions, eg.
- .PP
- .Vb 9
- \& /* 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\*(Aqs "CHIL" hardware available */
- \& void ENGINE_load_chil(void);
- \& ...
- \& /* Make ALL ENGINE implementations bundled with OpenSSL available */
- \& void ENGINE_load_builtin_engines(void);
- .Ve
- .PP
- Having called any of these functions, \s-1ENGINE\s0 objects would have been
- dynamically allocated and populated with these implementations and linked
- into OpenSSL's internal linked list. At this point it is important to
- mention an important \s-1API\s0 function;
- .PP
- .Vb 1
- \& void ENGINE_cleanup(void);
- .Ve
- .PP
- If no \s-1ENGINE API\s0 functions are called at all in an application, then there
- are no inherent memory leaks to worry about from the \s-1ENGINE\s0 functionality,
- however if any ENGINEs are loaded, even if they are never registered or
- used, it is necessary to use the \fIENGINE_cleanup()\fR function to
- correspondingly cleanup before program exit, if the caller wishes to avoid
- memory leaks. This mechanism uses an internal callback registration table
- so that any \s-1ENGINE API\s0 functionality that knows it requires cleanup can
- register its cleanup details to be called during \fIENGINE_cleanup()\fR. This
- approach allows \fIENGINE_cleanup()\fR to clean up after any \s-1ENGINE\s0 functionality
- at all that your program uses, yet doesn't automatically create linker
- dependencies to all possible \s-1ENGINE\s0 functionality \- only the cleanup
- callbacks required by the functionality you do use will be required by the
- linker.
- .PP
- The fact that ENGINEs are made visible to OpenSSL (and thus are linked into
- the program and loaded into memory at run-time) does not mean they are
- \&\*(L"registered\*(R" or called into use by OpenSSL automatically \- that behaviour
- is something for the application to control. Some applications
- will want to allow the user to specify exactly which \s-1ENGINE\s0 they want used
- if any is to be used at all. Others may prefer to load all support and have
- OpenSSL automatically use at run-time any \s-1ENGINE\s0 that is able to
- successfully initialise \- ie. to assume that this corresponds to
- acceleration hardware attached to the machine or some such thing. There are
- probably numerous other ways in which applications may prefer to handle
- things, so we will simply illustrate the consequences as they apply to a
- couple of simple cases and leave developers to consider these and the
- source code to openssl's builtin utilities as guides.
- .PP
- \&\fIUsing a specific \s-1ENGINE\s0 implementation\fR
- .PP
- Here we'll assume an application has been configured by its user or admin
- to want to use the \*(L"\s-1ACME\*(R" ENGINE\s0 if it is available in the version of
- OpenSSL the application was compiled with. If it is available, it should be
- used by default for all \s-1RSA, DSA,\s0 and symmetric cipher operations, otherwise
- OpenSSL should use its builtin software as per usual. The following code
- illustrates how to approach this;
- .PP
- .Vb 10
- \& ENGINE *e;
- \& const char *engine_id = "ACME";
- \& ENGINE_load_builtin_engines();
- \& e = ENGINE_by_id(engine_id);
- \& if(!e)
- \& /* the engine isn\*(Aqt available */
- \& return;
- \& if(!ENGINE_init(e)) {
- \& /* the engine couldn\*(Aqt initialise, release \*(Aqe\*(Aq */
- \& ENGINE_free(e);
- \& return;
- \& }
- \& if(!ENGINE_set_default_RSA(e))
- \& /* This should only happen when \*(Aqe\*(Aq can\*(Aqt 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);
- .Ve
- .PP
- \&\fIAutomatically using builtin \s-1ENGINE\s0 implementations\fR
- .PP
- Here we'll assume we want to load and register all \s-1ENGINE\s0 implementations
- bundled with OpenSSL, such that for any cryptographic algorithm required by
- OpenSSL \- if there is an \s-1ENGINE\s0 that implements it and can be initialised,
- it should be used. The following code illustrates how this can work;
- .PP
- .Vb 4
- \& /* 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();
- .Ve
- .PP
- That's all that's required. Eg. the next time OpenSSL tries to set up an
- \&\s-1RSA\s0 key, any bundled ENGINEs that implement \s-1RSA_METHOD\s0 will be passed to
- \&\fIENGINE_init()\fR and if any of those succeed, that \s-1ENGINE\s0 will be set as the
- default for \s-1RSA\s0 use from then on.
- .SS "Advanced configuration support"
- .IX Subsection "Advanced configuration support"
- There is a mechanism supported by the \s-1ENGINE\s0 framework that allows each
- \&\s-1ENGINE\s0 implementation to define an arbitrary set of configuration
- \&\*(L"commands\*(R" and expose them to OpenSSL and any applications based on
- OpenSSL. This mechanism is entirely based on the use of name-value pairs
- and assumes \s-1ASCII\s0 input (no unicode or \s-1UTF\s0 for now!), so it is ideal if
- applications want to provide a transparent way for users to provide
- arbitrary configuration \*(L"directives\*(R" directly to such ENGINEs. It is also
- possible for the application to dynamically interrogate the loaded \s-1ENGINE\s0
- implementations for the names, descriptions, and input flags of their
- available \*(L"control commands\*(R", providing a more flexible configuration
- scheme. However, if the user is expected to know which \s-1ENGINE\s0 device he/she
- is using (in the case of specialised hardware, this goes without saying)
- then applications may not need to concern themselves with discovering the
- supported control commands and simply prefer to pass settings into ENGINEs
- exactly as they are provided by the user.
- .PP
- Before illustrating how control commands work, it is worth mentioning what
- they are typically used for. Broadly speaking there are two uses for
- control commands; the first is to provide the necessary details to the
- implementation (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 any
- driver or config files it needs to load, required network addresses,
- smart-card identifiers, passwords to initialise protected devices,
- logging information, etc etc. This class of commands typically needs to be
- passed to an \s-1ENGINE\s0 \fBbefore\fR attempting to initialise it, ie. before
- calling \fIENGINE_init()\fR. The other class of commands consist of settings or
- operations that tweak certain behaviour or cause certain operations to take
- place, and these commands may work either before or after \fIENGINE_init()\fR, or
- in some cases both. \s-1ENGINE\s0 implementations should provide indications of
- this in the descriptions attached to builtin control commands and/or in
- external product documentation.
- .PP
- \&\fIIssuing control commands to an \s-1ENGINE\s0\fR
- .PP
- Let's illustrate by example; a function for which the caller supplies the
- name of the \s-1ENGINE\s0 it wishes to use, a table of string-pairs for use before
- initialisation, and another table for use after initialisation. Note that
- the string-pairs used for control commands consist of a command \*(L"name\*(R"
- followed by the command \*(L"parameter\*(R" \- the parameter could be \s-1NULL\s0 in some
- cases but the name can not. This function should initialise the \s-1ENGINE\s0
- (issuing the \*(L"pre\*(R" commands beforehand and the \*(L"post\*(R" commands afterwards)
- and set it as the default for everything except \s-1RAND\s0 and then return a
- boolean success or failure.
- .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] ? pre_cmds[1] : "(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() 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)\en", 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;
- \& }
- .Ve
- .PP
- Note that \fIENGINE_ctrl_cmd_string()\fR accepts a boolean argument that can
- relax the semantics of the function \- if set non-zero it will only return
- failure if the \s-1ENGINE\s0 supported the given command name but failed while
- executing it, if the \s-1ENGINE\s0 doesn't support the command name it will simply
- return success without doing anything. In this case we assume the user is
- only supplying commands specific to the given \s-1ENGINE\s0 so we set this to
- \&\s-1FALSE.\s0
- .PP
- \&\fIDiscovering supported control commands\fR
- .PP
- It is possible to discover at run-time the names, numerical-ids, descriptions
- and input parameters of the control commands supported by an \s-1ENGINE\s0 using a
- structural reference. Note that some control commands are defined by OpenSSL
- itself and it will intercept and handle these control commands on behalf of the
- \&\s-1ENGINE,\s0 ie. the \s-1ENGINE\s0's \fIctrl()\fR handler is not used for the control command.
- openssl/engine.h defines an index, \s-1ENGINE_CMD_BASE,\s0 that all control commands
- implemented by ENGINEs should be numbered from. Any command value lower than
- this symbol is considered a \*(L"generic\*(R" command is handled directly by the
- OpenSSL core routines.
- .PP
- It is using these \*(L"core\*(R" control commands that one can discover the the control
- commands implemented by a given \s-1ENGINE,\s0 specifically the commands;
- .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
- Whilst these commands are automatically processed by the OpenSSL framework code,
- they use various properties exposed by each \s-1ENGINE\s0 to process these
- queries. An \s-1ENGINE\s0 has 3 properties it exposes that can affect how this behaves;
- it can supply a \fIctrl()\fR handler, it can specify \s-1ENGINE_FLAGS_MANUAL_CMD_CTRL\s0 in
- the \s-1ENGINE\s0's flags, and it can expose an array of control command descriptions.
- If an \s-1ENGINE\s0 specifies the \s-1ENGINE_FLAGS_MANUAL_CMD_CTRL\s0 flag, then it will
- simply pass all these \*(L"core\*(R" control commands directly to the \s-1ENGINE\s0's \fIctrl()\fR
- handler (and thus, it must have supplied one), so it is up to the \s-1ENGINE\s0 to
- reply to these \*(L"discovery\*(R" commands itself. If that flag is not set, then the
- OpenSSL framework code will work with the following rules;
- .PP
- .Vb 9
- \& 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 ...
- .Ve
- .PP
- If the \s-1ENGINE\s0's array of control commands is empty then all other commands will
- fail, otherwise; \s-1ENGINE_CTRL_GET_FIRST_CMD_TYPE\s0 returns the identifier of
- the first command supported by the \s-1ENGINE, ENGINE_GET_NEXT_CMD_TYPE\s0 takes the
- identifier of a command supported by the \s-1ENGINE\s0 and returns the next command
- identifier or fails if there are no more, \s-1ENGINE_CMD_FROM_NAME\s0 takes a string
- name for a command and returns the corresponding identifier or fails if no such
- command name exists, and the remaining commands take a command identifier and
- return properties of the corresponding commands. All except
- \&\s-1ENGINE_CTRL_GET_FLAGS\s0 return the string length of a command name or description,
- or populate a supplied character buffer with a copy of the command name or
- description. \s-1ENGINE_CTRL_GET_FLAGS\s0 returns a bitwise-OR'd mask of the following
- possible values;
- .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
- If the \s-1ENGINE_CMD_FLAG_INTERNAL\s0 flag is set, then any other flags are purely
- informational to the caller \- this flag will prevent the command being usable
- for any higher-level \s-1ENGINE\s0 functions such as \fIENGINE_ctrl_cmd_string()\fR.
- \&\*(L"\s-1INTERNAL\*(R"\s0 commands are not intended to be exposed to text-based configuration
- by applications, administrations, users, etc. These can support arbitrary
- operations via \fIENGINE_ctrl()\fR, including passing to and/or from the control
- commands data of any arbitrary type. These commands are supported in the
- discovery mechanisms simply to allow applications determinie if an \s-1ENGINE\s0
- supports certain specific commands it might want to use (eg. application \*(L"foo\*(R"
- might query various ENGINEs to see if they implement \*(L"\s-1FOO_GET_VENDOR_LOGO_GIF\*(R"\s0 \-
- and \s-1ENGINE\s0 could therefore decide whether or not to support this \*(L"foo\*(R"\-specific
- extension).
- .SS "Future developments"
- .IX Subsection "Future developments"
- The \s-1ENGINE API\s0 and internal architecture is currently being reviewed. Slated for
- possible release in 0.9.8 is support for transparent loading of \*(L"dynamic\*(R"
- ENGINEs (built as self-contained shared-libraries). This would allow \s-1ENGINE\s0
- implementations to be provided independently of OpenSSL libraries and/or
- OpenSSL-based applications, and would also remove any requirement for
- applications to explicitly use the \*(L"dynamic\*(R" \s-1ENGINE\s0 to bind to shared-library
- implementations.
- .SH "SEE ALSO"
- .IX Header "SEE ALSO"
- \&\fIrsa\fR\|(3), \fIdsa\fR\|(3), \fIdh\fR\|(3), \fIrand\fR\|(3)
|