I've investigated lacks of documentation in the current OpenSSL
snapshot.

Method of investigation is quite simple

1. Run util/extract-names.pl  on the all pod files in the doc/crypto and
doc/ssl and produce sorted list of all function names referenced in the
NAME sections.

2. Take lists of exported symbols used in Windows DLL building
  (utils/libeay.num and utils/ssl.num) 

3. Use comm(1) to compare these lists

Results are quite discouraging.


library| exported | documened | other things documented |
       |          |           | (macros, intro pages)   |
-------+----------+-----------+-------------------------+
  ssl  |     258  |     159   |            52           |
crypto |    4012  |     683   |           159           |
-------+----------+-----------+-------------------------+

Of course, there are functions which are really documented, just non
mentioned in the NAME section of appropriate man page (which means
that symlink with such name is not installed, and user would be unable
to find documentation for this function)

There might be some semi-internal functions or exported variable, which
do not deserve its own manual pages.

But there are big omissions. 

For example entire family of 

X509_STORE functions, OCSP api, TS API are nont documetned.

I'm attaching here couple of POD files for EVP_PKEY_METHOD and
EVP_PKEY_ASN1_METHOD API, which we have written while developing ccgost
engine. Of course it would cover only 19 of more than 3 thousands undocumented
names, and not most widely used APIs. 

We also have some documentation about X509_STORE and OCSP API, 
published in the PDF format on
http://www.cryptocom.ru/OpenSource/OpenSSL_rus.html,  but it
has to be translated from Russian and converted into POD format.









----- End forwarded message -----
=pod

=head1 NAME

EVP_PKEY_METHOD, ENGINE_set_pkey_meths, EVP_PKEY_meth_new,
EVP_PKEY_meth_set_init, EVP_PKEY_meth_free, EVP_PKEY_meth_set_cleanup,
EVP_PKEY_meth_set_copy, EVP_PKEY_meth_set_paramgen, EVP_PKEY_meth_set_keygen,
EVP_PKEY_meth_set_sign, EVP_PKEY_meth_set_verify,
EVP_PKEY_meth_set_verify_recover, EVP_PKEY_meth_set_signctx,
EVP_PKEY_meth_set_verifyctx, EVP_PKEY_meth_set_encrypt,
EVP_PKEY_meth_set_decrypt, EVP_PKEY_meth_set_derive,
EVP_PKEY_meth_set_ctrl - Public key method manupulation routines

=head1 SYNOPSIS

  #include <openssl/engine.h>

  int ENGINE_set_pkey_meths(ENGINE *e,
      ENGINE_PKEY_METHS_PTR pkey_meths);

  #include <openssl/evp.h>

  EVP_PKEY_METHOD* EVP_PKEY_meth_new(int nid, int flags);
  void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
  void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
      int (*init)(EVP_PKEY_CTX *ctx));
  void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
      void (*cleanup)(EVP_PKEY_CTX *ctx));
  void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
      int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src));
  void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
      int (*paramgen_init)(EVP_PKEY_CTX *ctx),
      int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
  void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
      int (*keygen_init)(EVP_PKEY_CTX *ctx),
      int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey));
  void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
      int (*sign_init)(EVP_PKEY_CTX *ctx),
      int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
          const unsigned char *tbs, size_t tbslen));
  void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
      int (*verify_init)(EVP_PKEY_CTX *ctx),
      int (*verify)(EVP_PKEY_CTX *ctx,
          const unsigned char *sig, size_t siglen,
          const unsigned char *tbs, size_t tbslen));
  void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
      int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
      int (*verify_recover)(EVP_PKEY_CTX *ctx,
          unsigned char *rout, size_t *routlen,
          const unsigned char *sig, size_t siglen));
  void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
      int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
      int (*signctx)(EVP_PKEY_CTX *ctx,
          unsigned char *sig, size_t *siglen,
          EVP_MD_CTX *mctx));
  void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
      int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
      int (*verifyctx)(EVP_PKEY_CTX *ctx,
          const unsigned char *sig,int siglen,
          EVP_MD_CTX *mctx));
  void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
      int (*encrypt_init)(EVP_PKEY_CTX *ctx),
      int (*encrypt)(EVP_PKEY_CTX *ctx,
          unsigned char *out, size_t *outlen,
          const unsigned char *in, size_t inlen));
  void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
      int (*decrypt_init)(EVP_PKEY_CTX *ctx),
      int (*decrypt)(EVP_PKEY_CTX *ctx,
          unsigned char *out, size_t *outlen,
          const unsigned char *in, size_t inlen));
  void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
      int (*derive_init)(EVP_PKEY_CTX *ctx),
      int (*derive)(EVP_PKEY_CTX *ctx,
          unsigned char *key, size_t *keylen));
  void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
      int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
      int (*ctrl_str)(EVP_PKEY_CTX *ctx,
          const char *type, const char *value));

=head1 DESCRIPTION

EVP_PKEY_METHOD is an opaque structure that encapsulates all the
cryptographic operations with private/public keys.  It is not accessible
directly, but only through pointers and
EVP_PKEY_meth_set_*/EVP_PKEY_meth_get_* functions.

Each public key nid (if not alias) must have a personal EVP_PKEY_METHOD.

=head2 The way to provide a EVP_PKEY_METHOD for a loadable engine

A loadable engine cannot have a static EVP_PKEY_METHOD structure because it is
opaque.  So it must create it dynamically and register within the libcrypto.
The way is somewhat indirect.

The engine should provide (with ENGINE_set_pkey_meths() function) a callback
of the type ENGINE_PKEY_METHS_PTR.  That is, a function with a prototype

 int pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
                 const int **nids, int nid)

This function, when called as C<pkey_meths(e, NULL, &nids, 0)>, should return
in I<nids> a pointer to static array of supported nids, and their number as a
return value (or -1 on error).

When called as C<pkey_meths(e, &meth, NULL, nid)>, it should return in I<meth>
a pointer to EVP_PKEY_METHOD for the I<nid>, and a non-zero as a return value
(0 means error).

You must not call EVP_PKEY_meth_free() for a method whose corresponding
I<pkey_mehs> callback is already registered.

The following example shows the idiom:

 static EVP_PKEY_METHOD *meth = NULL, *another_meth = NULL;
 static int the_nids = { the_nid, the_another_nid };

 static int pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
                        const int **nids, int nid)
     {
     if (!pmeth)
         { *nids = the_nids; return sizeof(the_nids)/sizeof(int); }
     switch (nid)
         {
         case the_nid: { *pmeth = meth; return 1; }
         case the_another_nid: { *pmeth = another_meth; return 1; }
         default: { *pmeth = NULL; return 0; }
         }
     }

 static int bind_engine (ENGINE *e, const char *id)
     {
     /* some other initialization */
     if (!ENGINE_set_pkey_meths(e, pkey_meths))
         return 0;
     meth = EVP_PKEY_meth_new(the_nid, flags);
     EVP_PKEY_meth_set_init(meth, some_init_function);
     /* etc. */
     another_meth = EVP_PKEY_meth_new(the_another_nid, flags);
     EVP_PKEY_meth_set_init(another_meth, another_init_function);
     /* etc. */
     }

The order of initialization may be different, but all the methods are
registered (and will be freed appropriately) only after a successful
ENGINE_set_pkey_meths().  On the other hand, returning NULL from pkey_meths()
is okay.

=head2 Calling scheme of PKEY methods

All cryptographic operations are called from libcrypto by the following scheme:

  EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, engine);
  EVP_PKEY_<operation>_init(ctx);
  /* Various parameter setting control options */
  EVP_PKEY_<operation>(ctx, arguments);
  EVP_PKEY_CTX_free(ctx);

All the init methods called by EVP_PKEY_<operation>_init() have a prototype

  int op_init (EVP_PKEY_CTX *ctx)

They are called only if they are defined (NULL is okay) for the freshly
initialized EVP_PKEY_CTX with I<operation> field set to the corresponding
operation.

The prototypes and meaning of functions implementing cryptographic operations
are written in the descriptions of corresponding EVP_PKEY_meth_set_* methods.

=head2 Creating and destroying an EVP_PKEY_METHOD

=over 4

=item EVP_PKEY_meth_new()

Creates a new EVP_PKEY_METHOD for a nid I<id> with flags I<flags>.
EVP_PKEY_meth_new() adds a EVP_PKEY_FLAG_DYNAMIC flag to the method, which is
not public and means "This method was created dynamically and may be freed".
Other defined flags are:

=over 4

=item EVP_PKEY_FLAG_AUTOARGLEN

Means that the method is satisfied with the default behavior of argument
length handling in I<sign>, I<verify_recover>, I<encrypt>, I<decrypt> and
I<derive> callbacks.  See below for its description.

=back

=item EVP_PKEY_meth_free()

This functions is rarely needs to be called by hands.  It is needed only if
you encountered an error after you have acquired I<pmeth> but before you have
registered the I<pkey_meths> callback used to automatically free it.
EVP_PKEY_meth_free() frees I<pmeth> if it is dynamic.

=back

=head2 Setting PKEY method callbacks

=over 4

=item EVP_PKEY_meth_set_init()

Sets an init PKEY callback.  I<init> is used, if defined, to initialize an
EVP_PKEY_CTX just created as a last step of EVP_PKNEY_CTX_new.  Return value
of 0 or less is interpreted as error, >0 means success.

=item EVP_PKEY_meth_set_cleanup()

Sets a cleanup PKEY callback.  I<cleanup> is used, if defined, to undo actions
of init.  It is called as a first step of EVP_PKEY_CTX_free().

=item EVP_PKEY_meth_set_copy()

Sets a callback for finishing a copy operation for PKEY_CTX.  I<copy> is
called when I<*dst> is in the following state: its I<pmeth>, I<engine>,
I<pkey>, I<peerkey> and I<operation> fields have been copied from I<*src>
(that is, pointers point to the same locations, and underlying structures are
not copied, and reference counters for I<pkey> and I<peerkey> are increased),
I<data> and I<app_data> fields are NULL.  Return value of 0 or less is
interpreted as error, >0 means success.

=item EVP_PKEY_meth_set_paramgen()

Sets callbacks for public key parameters generation.  I<paramgen> is called
for a fresh EVP_PKEY and should fill its internal structure with generated
parameters.  Return value of 0 or less is interpreted as error, >0 means
success.

=item EVP_PKEY_meth_set_keygen()

Sets callbacks for key pair generation.  I<keygen> is called for a fresh
EVP_PKEY and should fill it with a generated key pair.  Where this callback
can get key generation parameters, depends on algorithm, but the typical ways
supported by the B<genpkey> OpenSSL command are the following.

>From external file:

=over 4

=item parameters are read from the external file pointed by the I<-paramfile>
parameter by PEM_read_bio_Parameters() which calls the corresponding
L<EVP_PKEY_ASN1_METHOD>'s I<param_decode> callback;

=item the returned EVP_PKEY pointer is used as a base for I<ctx> creation;

=item when called, the I<keygen> can take these parameters from I<ctx>->pkey,
typically by the call C<EVP_PKEY_copy_parameters(pkey, ctx-E<gt>pkey)>.

=back

>From public key options string:

=over 4

=item the named public key options, an argument of the I<-pkeyopt> command
line option, are set in I<ctx> by EVP_PKEY_CTX_ctrl_str(), using the
I<ctrl_str> callback; there may be several I<-pkeyopt> parameters in the command
line;

=item when called, the I<keygen> can take these parameters from I<ctx> in a
EVP_PKEY_METHOD-specific manner consistent with its I<ctrl_str> callback.

=back

Return value of 0 or less is interpreted as error, >0 means success.

=item EVP_PKEY_meth_set_sign()

Sets callbacks for signing.  I<sign> is called to calculate a signature.
I<tbs> and I<tbslen> pair of parameters may contain either a data to be signed
or the value of a calculated digest.  In the latter case a I<ctrl> callback
was called with I<type>==EVP_PKEY_CTRL_MD at some earlier moment for the same
EVP_PKEY_CTX, so the I<sign> callback can find this out as appropriate for the
EVP_PKEY_METHOD.  The I<siglen> parameters on input points to the value of
I<sig>'s length, if I<sig> is not NULL.  If the EVP_PKEY_METHOD's flags
contains EVP_PKEY_FLAG_AUTOARGLEN, I<sign> is called after a length check,
only for the real signing, not as a call for signature buffer length.
Otherwise it should handle a call for signature buffer length itself, that is,
I<sig>==NULL means that the caller asks for the buffer length only, and
I<sign> should return a value large enough in the I<siglen> parameters and 1
as a return value.  For the real signing it should return a real signature
length in the I<siglen> parameter and fill the I<sig> buffer with the
signature.  Return value of 0 or less is interpreted as error, >0 means
success.

=item EVP_PKEY_meth_set_verify()

Sets callbacks for detached signature verification.  I<verify> is called to
verify a detached signature.  I<tbs> and I<tbslen> pair of parameters may
contain either a data to be signed or the value of a calculated digest.  In
the latter case a I<ctrl> callback was called with I<type>==EVP_PKEY_CTRL_MD
at some earlier moment for the same EVP_PKEY_CTX, so the I<verify> callback
can find this out as appropriate for the EVP_PKEY_METHOD.  Return value >0
means successful verification, 0 means that verification failed, and <0 means
some other error, such as inappropriate digest for the signature algorithm.

=item EVP_PKEY_meth_set_verify_recover()

Sets callbacks for opaque signature verification.  The opaque signature is the
signature that contains the (transformed) signed data, so the verification
process extracts it.

The I<routlen> parameter of I<verify_recover> on input points to the value of
I<rout> buffer length if I<rout> is not NULL.  As for signing, if
EVP_PKEY_METHOD's flag EVP_PKEY_FLAG_AUTOARGLEN is set, the I<verify_recover>
is called only for the real verification and extraction of signed data.
Otherwise it should handle a call for signature buffer length itself, that is,
I<rout>==NULL means that the caller asks for the buffer length only, and
I<verify_recover> should return a value large enough in the I<routlen>
parameters and 1 as a return value.  For the real verification it should
return a real verified data length in I<routlen> and fill the I<rout> buffer
with the verified data.  Return value >0 means successful verification, 0
means that verification failed, and <0 means some other error, such as
inappropriate digest for the signature algorithm or buffer too small.

=item EVP_PKEY_meth_set_signctx()

Sets callbacks for signing a digest.  I<signctx> does the same that I<sign>
called for a digest except it is supplied with the digest context instead of
digest value and its nid in a I<ctrl> callback call.

=item EVP_PKEY_meth_set_verifyctx()

Sets callbacks for verifying a signature of a digest.  I<verifyctx> does the
same that I<verify> called for a digest except it is supplied with the digest
context instead of digest value and its nid in a I<ctrl> callback call.

=item EVP_PKEY_meth_set_encrypt()

Sets callbacks for a public key encryption.  The parameters handling and
return value of I<encrypt> are the same as for I<sign> callback except that
there is no such a thing as a digest encryption (that is, I<in> contains data,
not a digest value), and a public key is used instead of private.

=item EVP_PKEY_meth_set_decrypt()

Sets callbacks for a private key decryption.  The parameters handling and
return value for I<decrypt> are the same as for I<sign> callback except that
I<in> contains encrypted data.

=item EVP_PKEY_meth_set_derive()

Sets callbacks for deriving a (symmetric encryption) key from a pair of keys.
Before I<derive> is called, peer key must be set into I<ctx>.
This is done via C<EVP_PKEY_derive_set_peer> function.
If EVP_PKEY_METHOD's
flag EVP_PKEY_FLAG_AUTOARGLEN is set, this callback is not called to answer a
request for I<key> buffer length.  C<EVP_PKEY_size(ctx-E<gt>pkey)> is used for
the answer and in a check for a length.

=item EVP_PKEY_meth_set_ctrl()

Sets two control callbacks.

For I<ctrl> I<type> is the type of a parameter, and I<p1> and/or I<p2> is the
value.  For all the callbacks return value -2 means "command not supported",
and -1 means other error.  There are four standard types:

=over 4

=item EVP_PKEY_CTRL_MD

"Use this digest."  I<p2> is a C<const EVP_MD *> of a digest that will be
passed to the appropriate I<sign> or I<verify> callback.  Return value >0 means
success.

=item EVP_PKEY_CTRL_PEER_KEY

"Use this public key as a peer key for key derivation."  I<p2> is a pointer to
peer's public key (EVP_PKEY).  Return value <=0 means error, 1 means the
signal to the caller (EVP_PKEY_derive_set_peer) "I am fully satisfied with the
default behavior, do it for me, please", 2 means that I<ctrl> callback take the
all the responsibility for setting the peer's key.  The default behavior is:
check that I<ctx>->pkey and I<peer> have the same type; if I<peer> has
parameters, check that they are equal to I<ctx>->pkey's; then set
I<ctx>->peerkey to I<peer>, call I<ctrl> again with I<p1>==1 (the first call
is with I<p1>==0) and if successful (return value >0), increase the reference
counter for I<peer>.  The two-level scheme is used to allow the developer
slightly alter the default behavior without the need of doing reference
counting etc. by hands.

=item EVP_PKEY_CTRL_PKCS7_ENCRYPT

"Prepare PKCS#7 key encryption."  I<p2> is a C<PKCS7_RECIP_INFO *>.  Return
value >0 means that the context is ready to encrypt the key.

=item EVP_PKEY_CTRL_PKCS7_DECRYPT

"Prepare PKCS#7 key decryption."  I<p2> is a C<PKCS7_RECIP_INFO *>.  Return
value >0 means that the context is ready to decrypt the key.

=item EVP_PKEY_CTRL_PKCS7_SIGN

"Modify PKCS#7 SignerInfo, if needed".  Allows to modify the SignerInfo just
before it will be signed.  I<p2> is a C<PKCS7_SIGNER_INFO *>.  Return value >0
means success.  If the method supports signing, this ctrl must be supported,
even if you need not modify SignerInfo.

=back

Types with values greater than EVP_PKEY_ALG_CTRL are algorithm-specific.  This
may be used by I<ctrl_str> which is supplied with some name of a parameter,
not a value.

I<ctrl_str> is called by B<genpkey> command to set an arbitrary string
parameter.  I<type> is the name of the parameter, and I<value> is its value.
Return value >0 means success, <=0 means error.

=back

=head1 SEE ALSO

L<EVP_PKEY_ASN1_METHOD(3)|EVP_PKEY_ASN1_METHOD(3)>, L<genpkey(1)|genpkey(1)>

=cut
=pod

=head1 NAME

EVP_PKEY_ASN1_METHOD, ENGINE_set_pkey_asn1_meths, EVP_PKEY_asn1_new,
EVP_PKEY_asn1_free, EVP_PKEY_asn1_set_free, EVP_PKEY_asn1_set_public,
EVP_PKEY_asn1_set_private, EVP_PKEY_asn1_set_param, EVP_PKEY_asn1_set_ctrl,
EVP_PKEY_asn1_add_alias

=head1 SYNOPSIS

  #include <openssl/engine.h>

  int ENGINE_set_pkey_asn1_meths(ENGINE *e,
      ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths);

  #include <openssl/evp.h>

  EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int nid, int flags,
      const char *pem_str, const char *info);
  void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth);
  int EVP_PKEY_asn1_add_alias(int to, int from);
  void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
      void (*pkey_free)(EVP_PKEY *pkey));
  void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
      int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
      int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
      int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
      int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
          ASN1_PCTX *pctx),
      int (*pkey_size)(const EVP_PKEY *pk),
      int (*pkey_bits)(const EVP_PKEY *pk));
  void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
      int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
      int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
      int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
          ASN1_PCTX *pctx));
  void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
      int (*param_decode)(EVP_PKEY *pkey,
          const unsigned char **pder, int derlen),
      int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
      int (*param_missing)(const EVP_PKEY *pk),
      int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
      int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
      int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
          ASN1_PCTX *pctx));
  void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
      int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2));

=head1 DESCRIPTION

EVP_PKEY_ASN1_METHOD is an opaque structure that encapsulates all the
operations with ASN1 representation of key pairs, signatures etc. for a given
public key algorithm.  It is not accessible directly, but only through
pointers and EVP_PKEY_asn1_set_* functions.

Each public key nid must have a personal EVP_PKEY_ASN1_METHOD.

=head2 The way to provide a EVP_PKEY_ASN1_METHOD for a loadable engine

A loadable engine cannot have a static EVP_PKEY_ASN1_METHOD structure because
it is opaque.  So it must create it dynamically and register within the
libcrypto.  The way is somewhat indirect.

The engine should provide (with ENGINE_set_pkey_asn1_meths() function) a
callback of the type ENGINE_PKEY_ASN1_METHS_PTR.  That is, a function with a
prototype

  int pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
                       const int **nids, int nid)

This function, when called as C<pkey_asn1_meths(e, NULL, &nids, 0)>, should
return in I<nids> a pointer to static array of supported nids, and their
number as a return value (or -1 on error).

When called as C<pkey_asn1_meths(e, &meth, NULL, nid)>, it should return in
I<meth> a pointer to EVP_PKEY_ASN1_METHOD for the I<nid>, and a non-zero as a
return value (0 means error).

You must not call EVP_PKEY_asn1_free() for a method whose corresponding
I<pkey_asn1_meths> callback is already registered.

The following example shows the idiom:

  static EVP_PKEY_ASN1_METHOD *meth = NULL, *another_meth = NULL;
  static int the_nids = { the_nid, the_another_nid };

  static int pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
      const int **nids, int nid)
      {
      if (!ameth)
          { *nids = the_nids; return sizeof(the_nids)/sizeof(int); }
      switch (nid)
          {
          case the_nid: { *ameth = meth; return 1; }
          case the_another_nid: { *ameth = another_meth; return 1; }
          default: { *ameth = NULL; return 0; }
          }
      }

  static int bind_engine (ENGINE *e, const char *id)
      {
      /* some other initialization */
      if (!ENGINE_set_pkey_asn1_meths(e, pkey_asn1_meths))
          return 0;
      meth = EVP_PKEY_ASN1_new(the_nid, flags, pemstr1, info1);
      EVP_PKEY_asn1_set_free(meth, some_free_function);
      /* etc. */
      another_meth = EVP_PKEY_ASN1_new(the_another_nid, flags,
          pemstr2, info2);
      EVP_PKEY_asn1_set_free(another_meth, another_free_function);
      /* etc. */
      }

The order of initialization may be different, but all the methods are
registered (and will be freed appropriately) only after a successful
ENGINE_set_pkey_asn1_meths().  On the other hand, returning NULL from
pkey_asn1_meths() is okay.

=head2 Creating and destroying an EVP_PKEY_ASN1_METHOD

=over 4

=item EVP_PKEY_asn1_new()

Creates a new EVP_PKEY_ASN1_METHOD for a nid I<id> with flags I<flags>, PEM
identification string I<pem_str> and information string I<info>.

EVP_PKEY_ASN1_new() automatically adds ASN1_PKEY_DYNAMIC to I<flags>.  This
flag means that the method was created automatically and EVP_PKEY_asn1_free
should delete it, if called.  Other defined flags are

=over 4

=item ASN1_PKEY_ALIAS

This method is for the alias nid.  This flag is not usually used directly,
EVP_PKEY_asn1_add_alias() is used instead.

=item ASN1_PKEY_SIGPARAM_NULL

When signing, SignatureInfo.algorithmIdentifier.parameters will be ASN1 NULL,
not absent at all.

=back

The I<pem_str> string is used to identify the method when reading information
in PEM format.  Then the base64-decoded ASN1 content is passed to the correct
method.

The I<info> parameter is output by B<openssl list-public-key-algorithms>.

The I<pem_str> and I<info> strings are copied by EVP_PKEY_asn1_new().

Returns a pointer to the created method.

=item EVP_PKEY_asn1_free()

Frees the method if it is dynamic.  This functions is rarely needs to be
called by hands.  It is needed only if you encountered an error after you have
acquired I<ameth> but before you have registered the I<pkey_asn1_meths>
callback used to automatically free it.

=item EVP_PKEY_asn1_add_alias()

Creates a method for the nid I<from> that states that I<from> is an alias for
I<to> and does nothing more.  The method, if created by an engine, does not
belong to it and should not (and cannot be) mentioned by the
I<pkey_asn1_meths> callback.  The return value is 1 for success and 0 for
error.

=back

=head2 Setting ASN1 method callbacks

=over 4

=item EVP_PKEY_asn1_set_free()

Sets a cleanup callback for EVP_PKEY.  The callback is called just before the
pkey's storage is freed.

=item EVP_PKEY_asn1_set_public()

Sets public key encoding callbacks.

The I<pub_decode> is called from X509_PUBKEY_get() to finally fill I<pk> from
I<pub>.  On input the I<pk> has its type, engine and ameth set.  Return value
of non-zero means success, 0 means error.

The I<pub_encode> is called from X509_PUBKEY_set() to fill the just created
I<pub> from I<pk>.  The I<pkey> field of I<pub> is not filled automatically.
Return value of non-zero means success, 0 means error.

The I<pub_cmp> is called from EVP_PKEY_cmp() for the final check of two
EVP_PKEYs for equality.  It must return 0 or 1 I<only>.  It should return 1 if
public components of its arguments are equal.  It may skip checking the
parameters for equality because EVP_PKEY_cmp() calls I<param_cmp> before the
call to I<pub_cmp>.

The I<pub_print> is called from EVP_PKEY_print_public() to print a public key
with parameters in a human-readable form.  The I<indent> parameter is the
requested indent of the text.  It may be passed to BIO_indent().  I<ctx> is a
pointer to ASN1 printing context.  It may be NULL, and usually is.

The I<pkey_size> callback, called from EVP_PKEY_size(), should return an upper
limit for the size of the output of any public key operation with I<pk>.  It
is used to allocate buffers.  The size of a real operation output may be less.

The I<pkey_bits> callback, called from EVP_PKEY_bits(), should return a size
of a critical component in bits.

=item EVP_PKEY_asn1_set_private()

Sets private key encoding callbacks.

The I<priv_decode> is called from EVP_PKCS82PKEY() to finally fill I<pk> from
I<p8inf>.  On input the I<pk> has its type, engine and ameth set.  Return value
of non-zero means success, 0 means error.

The I<priv_encode> is called from EVP_PKEY2PKCS8_broken() to fill the just
created I<p8> from I<pk>.  Return value of non-zero means success, 0 means
error.

The I<priv_print> is called from EVP_PKEY_print_private() to print a private
key with parameters in a human-readable form.  The I<indent> parameter is the
requested indent of the text.  It may be passed to BIO_indent().  I<ctx> is a
pointer to ASN1 printing context.  It may be NULL, and usually is.

=item EVP_PKEY_asn1_set_param()

Sets public key parameters encoding callbacks.

I<param_decode> is called from PEM_read_bio_Parameters() to fill a fresh
I<pkey> with parameters read from DER encoding.  I<*pder> on input points to
the beginning of the DER buffer, and I<derlen> contains its length.  On output
I<*pder> should point to the first unused byte.  The rest of the buffer is
ignored by PEM_read_bio_Parameters().  The non-zero return value means
success, 0 means error.

I<param_encode> is called from PEM_write_bio_Parameters() via
PEM_ASN1_write_bio() to DER-encode key parameters.  It is called twice, first
with I<pder>==NULL to get a needed buffer length and then with the I<pder>
pointing to a pointer to the actual buffer.  The return value is the buffer
length, needed in the first call and used in the second.  I<*pder> after the
second call should point to the first unused position in (or after) the
buffer.

I<param_missing> is called from EVP_PKEY_missing_parameters() and should
return 1 if and only if the I<pkey> does not contain some mandatory
parameters.  Otherwise it should return 0.

I<param_copy> is called from EVP_PKEY_copy_parameters() and should copy all
the parameters from I<from> to I<to> EVP_PKEY.  Return value of 1 means
success, 0 means error.

I<param_cmp> is called from EVP_PKEY_cmp_parameters() to compare parameters.
It should return 1 if parameters are equal and 0 if not, or if error is
encountered.

The I<param_print> is called from EVP_PKEY_print_params() to print the
parameters in a human-readable form.  The I<indent> parameter is the requested
indent of the text.  It may be passed to BIO_indent().  I<ctx> is a pointer to
ASN1 printing context.  It may be NULL, and usually is.

=item EVP_PKEY_asn1_set_ctrl()

Sets a control function.  I<op> is the operation, and I<arg1> and/or I<arg2>
is the value.  There are three standard types:

=over 4

=item ASN1_PKEY_CTRL_PKCS7_SIGN

I<arg2> is a pointer to PKCS7_SIGNER_INFO.  The structure is to be updated by
the callback according to the algorithm (that is, the necessary OIDs and
AlgorithmIdentifiers).

I<arg1> is the context, in which the call is made.  Currently only 0 have a
meaning of "Initialize the structure".

The typical idiom here is like this:

  if (arg1 == 0)
      {
      X509_ALGOR *alg_digest, *alg_signature;
      PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg_digest,
          &alg_signature);
      X509_ALGOR_set0(alg_digest, OBJ_nid2obj(nid_digest),
          asn1_param_digest, 0);
      X509_ALGOR_set0(alg_signature, OBJ_nid2obj(nid_signature),
          asn1_param_signature, 0);
      }

=item ASN1_PKEY_CTRL_PKCS7_ENCRYPT

I<arg2> is a pointer to PKCS7_RECIP_INFO.  The structure is to be updated by
the callback according to the algorithm (that is, the necessary OIDs and
AlgorithmIdentifiers).

I<arg1> is the context, in which the call is made.  Currently only 0 have a
meaning of "Initialize the structure".

The typical idiom here is like this:

  if (arg1 == 0)
      {
      X509_ALGOR *alg_encrypt;
      PKCS7_RECIP_INFO_get0_alg(arg2, &alg_encrypt);
      X509_ALGOR_set0(alg_encrypt, OBJ_nid2obj(nid_encrypt),
          asn1_param_encrypt, 0);
      }

=item ASN1_PKEY_CTRL_DEFAULT_MD_NID

I<arg2> is C<int *> and the callback should write there NID of the default
digest for this public key signature algorithm.

On success return value 2 means that the returned digest is mandatory, 1 means
that this is the default digest, but not the only allowed one.

=back

Return value >0 means success, -2 means that this operation is not supported
for this key type, other values mean failure.

=head1 SEE ALSO

L<EVP_PKCS82PKEY(3)|EVP_PKCS82PKEY(3)>,
L<EVP_PKEY2PKCS8_broken(3)|EVP_PKEY2PKCS8_broken(3)>,
L<EVP_PKEY_bits(3)|EVP_PKEY_bits(3)>, L<EVP_PKEY_cmp(3)|EVP_PKEY_cmp(3)>,
L<EVP_PKEY_cmp_parameters(3)|EVP_PKEY_cmp_parameters(3)>,
L<EVP_PKEY_copy_parameters(3)|EVP_PKEY_copy_parameters(3)>,
L<EVP_PKEY_missing_parameters(3)|EVP_PKEY_missing_parameters(3)>,
L<EVP_PKEY_print_params(3)|EVP_PKEY_print_params(3)>,
L<EVP_PKEY_print_private(3)|EVP_PKEY_print_private(3)>,
L<EVP_PKEY_print_public(3)|EVP_PKEY_print_public(3)>,
L<EVP_PKEY_size(3)|EVP_PKEY_size(3)>,
L<PEM_ASN1_write_bio(3)|PEM_ASN1_write_bio(3)>,
L<PEM_read_bio_Parameters(3)|PEM_read_bio_Parameters(3)>,
L<PEM_write_bio_Parameters(3)|PEM_write_bio_Parameters(3)>,
L<X509_PUBKEY_get(3)|X509_PUBKEY_get(3)>,
L<X509_PUBKEY_set(3)|X509_PUBKEY_set(3)>

=cut

Reply via email to