Added SILC Thread Queue API
[silc.git] / lib / silccrypt / silcpkcs.h
index f954542499ebb7261d077db5081cc2ccad0577f1..2fd34f7490650fb731eda7c30007401524b1f626 100644 (file)
@@ -1,10 +1,10 @@
 /*
 
-  silcpkcs.h 
+  silcpkcs.h
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2002 Pekka Riikonen
+  Copyright (C) 1997 - 2007 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
 
 */
 
-#ifndef SILCPKCS_H
-#define SILCPKCS_H
-
 /****h* silccrypt/SILC PKCS Interface
  *
  * DESCRIPTION
  *
- *    This is the interface for public key cryptosystems, and various
- *    utility functions related to public keys and private keys.  This
- *    interface also defines the actual PKCS objects, public keys and
- *    private keys.  The interface is generic PKCS interface, which has
- *    capability of supporting any kind of public key algorithm.  This
- *    interface also implements the SILC Public Key and routines for
- *    encoding and decoding SILC Public Key (as defined by the SILC
- *    protocol specification).  Interface or encrypting, decrypting,
- *    producing digital signatures and verifying digital signatures are
- *    also defined in this header.
+ * SILC PKCS API provides generic interface for performing various
+ * public key cryptography related operations with different types of
+ * public and private keys.  Support for loading and saving of different
+ * types of public key and private keys are also provided.
  *
  ***/
 
-/****s* silccrypt/SilcPKCSAPI/SilcPKCS
- *
- * NAME
- *
- *    typedef struct SilcPKCSStruct *SilcPKCS;
- *
- * DESCRIPTION
- *
- *    This context is the actual PKCS context and is allocated
- *    by silc_pkcs_alloc and given as argument usually to all
- *    silc_pkcs_* functions.  It is freed by the silc_pkcs_free
- *    function.
- *
- ***/
-typedef struct SilcPKCSStruct *SilcPKCS;
+#ifndef SILCPKCS_H
+#define SILCPKCS_H
 
-/* The default SILC PKCS (Public Key Cryptosystem) object to represent
-   any PKCS in SILC. */
-typedef struct SilcPKCSObjectStruct {
-  char *name;
-  int (*init)(void *, SilcUInt32, SilcRng);
-  void (*clear_keys)(void *);
-  unsigned char *(*get_public_key)(void *, SilcUInt32 *);
-  unsigned char *(*get_private_key)(void *, SilcUInt32 *);
-  SilcUInt32 (*set_public_key)(void *, unsigned char *, SilcUInt32);
-  SilcUInt32 (*set_private_key)(void *, unsigned char *, SilcUInt32);
-  SilcUInt32 (*context_len)();
-  int (*encrypt)(void *, unsigned char *, SilcUInt32,
-                unsigned char *, SilcUInt32 *);
-  int (*decrypt)(void *, unsigned char *, SilcUInt32,
-                unsigned char *, SilcUInt32 *);
-  int (*sign)(void *, unsigned char *, SilcUInt32,
-             unsigned char *, SilcUInt32 *);
-  int (*verify)(void *, unsigned char *, SilcUInt32,
-               unsigned char *, SilcUInt32);
-} SilcPKCSObject;
+/* Forward declarations */
+typedef struct SilcPKCSAlgorithmStruct SilcPKCSAlgorithm;
+typedef struct SilcPKCSObjectStruct SilcPKCSObject;
 
-/****s* silccrypt/SilcPKCSAPI/SilcPublicKey
+/****d* silccrypt/SilcPKCSAPI/SilcPKCSType
  *
  * NAME
  *
- *    typedef struct { ... } *SilcPublicKey, SilcPublicKeyStruct;
+ *    typedef enum { ... } SilcPKCSType;
  *
  * DESCRIPTION
  *
- *    SILC style public key object.  Public key is read from file to this
- *    object.  Public keys received from network must be in this format as
- *    well.  The format is defined by the SILC protocol specification.
- *    This object is allocated by silc_pkcs_public_key_alloc and freed
- *    by silc_pkcs_public_key_free.  The object is given as argument to
- *    all silc_pkcs_public_key_* functions.
+ *    Supported public key cryptosystem types.
  *
  * SOURCE
  */
-typedef struct {
-  SilcUInt16 pk_type;          /* Public key type (SilcSKEPKType) */
-  SilcUInt32 len;
-  char *name;
-  char *identifier;
-  unsigned char *pk;
-  SilcUInt32 pk_len;
-} *SilcPublicKey, SilcPublicKeyStruct;
+typedef enum {
+  SILC_PKCS_SILC    = 1,       /* SILC PKCS */
+  SILC_PKCS_SSH2    = 2,       /* SSH2 PKCS */
+  SILC_PKCS_X509V3  = 3,       /* X.509v3 PKCS */
+  SILC_PKCS_OPENPGP = 4,       /* OpenPGP PKCS */
+  SILC_PKCS_SPKI    = 5,       /* SPKI PKCS (not supported) */
+  SILC_PKCS_ANY     = 0,
+} SilcPKCSType;
 /***/
 
-/****s* silccrypt/SilcPKCSAPI/SilcPublicKeyIdentifier
+/****s* silccrypt/SilcPKCSAPI/SilcPublicKey
  *
  * NAME
  *
- *    typedef struct { ... } *SilcPublicKeyIdentifier,
- *                            SilcPublicKeyIdentifierStruct;
+ *    typedef struct { ... } *SilcPublicKey;
  *
  * DESCRIPTION
  *
- *    Decoded SILC Public Key identifier.  Note that some of the fields
- *    may be NULL.  This context is allocated by the function
- *    silc_pkcs_decode_identifier and freed by silc_pkcs_free_identifier.
- *    The identifier in SilcPublicKey is the `identifier' field, which
- *    can be given as argument to silc_pkcs_decode_identifier.
+ *    This context represents any kind of PKCS public key.  It can be
+ *    allocated by silc_pkcs_public_key_alloc and is freed by the
+ *    silc_pkcs_public_key_free.  The PKCS specific public key context
+ *    can be retrieved by calling silc_pkcs_public_key_get_pkcs.
  *
  * SOURCE
  */
-typedef struct {
-  char *username;
-  char *host;
-  char *realname;
-  char *email;
-  char *org;
-  char *country;
-} *SilcPublicKeyIdentifier, SilcPublicKeyIdentifierStruct;
+typedef struct SilcPublicKeyStruct {
+  SilcPKCSObject *pkcs;                /* PKCS */
+  const SilcPKCSAlgorithm *alg;        /* PKCS algorithm */
+  void *public_key;            /* PKCS specific public key */
+} *SilcPublicKey;
 /***/
 
 /****s* silccrypt/SilcPKCSAPI/SilcPrivateKey
  *
  * NAME
  *
- *    typedef struct { ... } *SilcPrivateKey, SilcPrivateKeyStruct;
+ *    typedef struct { ... } *SilcPrivateKey;
  *
  * DESCRIPTION
  *
- *    SILC style private key object.  Public key is read from file to this
- *    object.  This object is allocated by silc_pkcs_private_key_alloc and
- *    freed by silc_pkcs_private_key_free.  The object is given as argument
- *    to all silc_pkcs_private_key_* functions.
+ *    This context represents any kind of PKCS private key.  The PKCS specific
+ *    key context can be retrieved by calling silc_pkcs_private_key_get_pkcs.
  *
- ***/
-typedef struct {
-  char *name;
-  unsigned char *prv;
-  SilcUInt32 prv_len;
-} *SilcPrivateKey, SilcPrivateKeyStruct;
-
-/* Public and private key file headers */
-#define SILC_PKCS_PUBLIC_KEYFILE_BEGIN "-----BEGIN SILC PUBLIC KEY-----\n"
-#define SILC_PKCS_PUBLIC_KEYFILE_END "\n-----END SILC PUBLIC KEY-----\n"
-#define SILC_PKCS_PRIVATE_KEYFILE_BEGIN "-----BEGIN SILC PRIVATE KEY-----\n"
-#define SILC_PKCS_PRIVATE_KEYFILE_END "\n-----END SILC PRIVATE KEY-----\n"
-
-/* Public and private key file encoding types */
-#define SILC_PKCS_FILE_BIN 0
-#define SILC_PKCS_FILE_PEM 1
-
-/* Marks for all PKCS in silc. This can be used in silc_pkcs_unregister
-   to unregister all PKCS at once. */
-#define SILC_ALL_PKCS ((SilcPKCSObject *)1)
-
-/* Static list of PKCS for silc_pkcs_register_default(). */
-extern DLLAPI const SilcPKCSObject silc_default_pkcs[];
-
-/* Default PKXS in the SILC protocol */
-#define SILC_DEFAULT_PKCS "rsa"
-
-/* Macros */
-
-/* Macros used to implement the SILC PKCS API */
-
-/* XXX: This needs slight redesigning. These needs to be made even
-   more generic. I don't like that the actual prime generation is done
-   in PKCS_API_INIT. The primes used in key generation should be sent
-   as argument to the init function. By doing this we would achieve
-   that PKCS could be used as SIM's. The only requirement would be
-   that they are compiled against GMP (well, actually even that would
-   not be a requirement, but the most generic case anyway). The new init
-   would look something like this:
-
-   #define SILC_PKCS_API_INIT(pkcs) \
-   inline int silc_##pkcs##_init(void *context, SilcUInt32 keylen, \
-                                 void *p1, void *p2)
-
-   Now we wouldn't have to send the SilcRng object since the primes are
-   provided as arguments. To send them as void * they could actually be
-   used as in anyway for real (MP_INT (SilcMPInt) or even something else
-   (the pointer could be kludged to be something else in the module))
-   (Plus, the SilcRng object management in prime generation would be
-   simpler and better what it is now (in silcprimegen.c, that is)).
-*/
-
-#define SILC_PKCS_API_INIT(pkcs) \
-int silc_##pkcs##_init(void *context, SilcUInt32 keylen, \
-                      SilcRng rng)
-#define SILC_PKCS_API_CLEAR_KEYS(pkcs) \
-void silc_##pkcs##_clear_keys(void *context)
-#define SILC_PKCS_API_GET_PUBLIC_KEY(pkcs) \
-unsigned char *silc_##pkcs##_get_public_key(void *context, \
-                                            SilcUInt32 *ret_len)
-#define SILC_PKCS_API_GET_PRIVATE_KEY(pkcs) \
-unsigned char *silc_##pkcs##_get_private_key(void *context, \
-                                             SilcUInt32 *ret_len)
-#define SILC_PKCS_API_SET_PUBLIC_KEY(pkcs) \
-SilcUInt32 silc_##pkcs##_set_public_key(void *context, unsigned char *key_data, \
-                                        SilcUInt32 key_len)
-#define SILC_PKCS_API_SET_PRIVATE_KEY(pkcs) \
-SilcUInt32 silc_##pkcs##_set_private_key(void *context, unsigned char *key_data, \
-                                         SilcUInt32 key_len)
-#define SILC_PKCS_API_CONTEXT_LEN(pkcs) \
-SilcUInt32 silc_##pkcs##_context_len()
-#define SILC_PKCS_API_ENCRYPT(pkcs) \
-int silc_##pkcs##_encrypt(void *context, \
-                         unsigned char *src, \
-                         SilcUInt32 src_len, \
-                         unsigned char *dst, \
-                         SilcUInt32 *dst_len)
-#define SILC_PKCS_API_DECRYPT(pkcs) \
-int silc_##pkcs##_decrypt(void *context, \
-                         unsigned char *src, \
-                         SilcUInt32 src_len, \
-                         unsigned char *dst, \
-                         SilcUInt32 *dst_len)
-#define SILC_PKCS_API_SIGN(pkcs) \
-int silc_##pkcs##_sign(void *context, \
-                      unsigned char *src, \
-                      SilcUInt32 src_len, \
-                      unsigned char *dst, \
-                      SilcUInt32 *dst_len)
-#define SILC_PKCS_API_VERIFY(pkcs) \
-int silc_##pkcs##_verify(void *context, \
-                        unsigned char *signature, \
-                        SilcUInt32 signature_len, \
-                        unsigned char *data, \
-                        SilcUInt32 data_len)
-
-/* Prototypes */
+ * SOURCE
+ */
+typedef struct SilcPrivateKeyStruct {
+  SilcPKCSObject *pkcs;                /* PKCS */
+  const SilcPKCSAlgorithm *alg;        /* PKCS algorithm */
+  void *private_key;           /* PKCS specific private key */
+} *SilcPrivateKey;
+/***/
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_register
+/****d* silccrypt/SilcPKCSAPI/SilcPKCSFileEncoding
  *
- * SYNOPSIS
+ * NAME
  *
- *    bool silc_pkcs_register(const SilcPKCSObject *pkcs);
+ *    typedef enum { ... } SilcPKCSType
  *
  * DESCRIPTION
  *
- *    Registers a new PKCS into the SILC.  This function is used
- *    at the initialization of the SILC.  All registered PKCSs
- *    should be unregistered with silc_pkcs_unregister.  The `pkcs' includes
- *    the name of the PKCS and member functions for the algorithm.  Usually
- *    this function is not called directly.  Instead, application can call
- *    the silc_pkcs_register_default to register all PKCSs that are
- *    builtin the sources.  Returns FALSE on error.
+ *    Public and private key file encoding types.
  *
- ***/
-bool silc_pkcs_register(const SilcPKCSObject *pkcs);
+ * SOURCE
+ */
+typedef enum {
+  SILC_PKCS_FILE_BIN,          /* Binary encoding */
+  SILC_PKCS_FILE_BASE64                /* Base64 encoding */
+} SilcPKCSFileEncoding;
+/***/
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister
+/****f* silccrypt/SilcPKCSAPI/SilcPKCSEncryptCb
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_unregister(SilcPKCSObject *pkcs);
+ *    typedef void (*SilcPKCSEncryptCb)(SilcBool success,
+ *                                      const unsigned char *encrypted,
+ *                                      SilcUInt32 encrypted_len,
+ *                                      void *context);
  *
  * DESCRIPTION
  *
- *    Unregister a PKCS from the SILC. Returns FALSE on error.
+ *    Encryption callback.  This callback is given as argument to the
+ *    silc_pkcs_encrypt and the encrypted data is delivered to the caller
+ *    in this callback.  The `encrypted' is the encrypted data.  If the
+ *    `success' is FALSE the encryption operation failed.
  *
  ***/
-bool silc_pkcs_unregister(SilcPKCSObject *pkcs);
+typedef void (*SilcPKCSEncryptCb)(SilcBool success,
+                                 const unsigned char *encrypted,
+                                 SilcUInt32 encrypted_len,
+                                 void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_register_default
+/****f* silccrypt/SilcPKCSAPI/SilcPKCSDecryptCb
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_register_default(void);
+ *    typedef void (*SilcPKCSDecryptCb)(SilcBool success,
+ *                                      const unsigned char *decrypted,
+ *                                      SilcUInt32 decrypted_len,
+ *                                      void *context);
  *
  * DESCRIPTION
  *
- *    Registers all the default PKCS (all builtin PKCS).  The application may
- *    use this to register the default PKCS if specific PKCS in any specific
- *    order is not wanted. Returns FALSE on error.
+ *    Decryption callback.  This callback is given as argument to the
+ *    silc_pkcs_decrypt and the decrypted data is delivered to the caller
+ *    in this callback.  The `decrypted' is the decrypted data.  If the
+ *    `success' is FALSE the decryption operation failed.
  *
  ***/
-bool silc_pkcs_register_default(void);
+typedef void (*SilcPKCSDecryptCb)(SilcBool success,
+                                 const unsigned char *decrypted,
+                                 SilcUInt32 decrypted_len,
+                                 void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister_all
+/****f* silccrypt/SilcPKCSAPI/SilcPKCSSignCb
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_unregister_all(void);
+ *    typedef void (*SilcPKCSSignCb)(SilcBool success,
+ *                                   const unsigned char *signature,
+ *                                   SilcUInt32 signature_len,
+ *                                   void *context);
  *
  * DESCRIPTION
  *
- *    Returns FALSE on error.
+ *    Signature callback.  This callback is given as argument to the
+ *    silc_pkcs_sign and the digitally signed data is delivered to the caller
+ *    in this callback.  The `signature' is the signature data.  If the
+ *    `success' is FALSE the signature operation failed.
  *
  ***/
-bool silc_pkcs_unregister_all(void);
+typedef void (*SilcPKCSSignCb)(SilcBool success,
+                              const unsigned char *signature,
+                              SilcUInt32 signature_len,
+                              void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_alloc
+/****f* silccrypt/SilcPKCSAPI/SilcPKCSVerifyCb
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_alloc(const unsigned char *name, SilcPKCS *new_pkcs);
+ *    typedef void (*SilcPKCSVerifyCb)(SilcBool success, void *context);
  *
  * DESCRIPTION
  *
- *    Allocates a new SilcPKCS object.  The new allocated object is returned
- *    to the 'new_pkcs' argument.  Returns FALSE on error.
+ *    Verification callback.  This callback is given as argument to the
+ *    silc_pkcs_verify and the result of the signature verification is
+ *    deliver to the caller in this callback.  If the `success' is FALSE
+ *    the signature verification failed.
  *
  ***/
-bool silc_pkcs_alloc(const unsigned char *name, SilcPKCS *new_pkcs);
+typedef void (*SilcPKCSVerifyCb)(SilcBool success, void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_free
- *
- * SYNOPSIS
- *
- *    void silc_pkcs_free(SilcPKCS pkcs);
- *
- * DESCRIPTION
- *
- *    Frees the PKCS object.
- *
- ***/
-void silc_pkcs_free(SilcPKCS pkcs);
+#include "silcpkcs_i.h"
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_is_supported
- *
- * SYNOPSIS
- *
- *    bool silc_pkcs_is_supported(const unsigned char *name);
- *
- * DESCRIPTION
- *
- *    Returns TRUE if PKCS algorithm `name' is supported.
- *
- ***/
-bool silc_pkcs_is_supported(const unsigned char *name);
+/* Marks for all PKCS in. This can be used in silc_pkcs_unregister to
+   unregister all PKCS at once. */
+#define SILC_ALL_PKCS ((SilcPKCSObject *)1)
+#define SILC_ALL_PKCS_ALG ((SilcPKCSAlgorithm *)1)
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_supported
- *
- * SYNOPSIS
- *
- *    char *silc_pkcs_get_supported(void);
- *
- * DESCRIPTION
- *
- *    Returns comma separated list of supported PKCS algorithms.
- *
- ***/
-char *silc_pkcs_get_supported(void);
+/* Static lists of PKCS and PKCS algorithms. */
+extern DLLAPI const SilcPKCSObject silc_default_pkcs[];
+extern DLLAPI const SilcPKCSAlgorithm silc_default_pkcs_alg[];
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_generate_key
- *
- * SYNOPSIS
- *
- *    bool silc_pkcs_generate_key(SilcPKCS pkcs, SilcUInt32 bits_key_len,
- *                               SilcRng rng);
- *
- * DESCRIPTION
- *
- *    Generate new key pair into the `pkcs' context. Returns FALSE on error.
- *
- ***/
-bool silc_pkcs_generate_key(SilcPKCS pkcs, SilcUInt32 bits_key_len,
-                           SilcRng rng);
+/* Prototypes */
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_key_len
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_register
  *
  * SYNOPSIS
  *
- *    SilcUInt32 silc_pkcs_get_key_len(SilcPKCS self);
+ *    SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
  *
  * DESCRIPTION
  *
- *    Returns the length of the key.
+ *    Registers a new PKCS into the crypto library.  This function is used
+ *    at the initialization of an application.  All registered PKCSs
+ *    should be unregistered with silc_pkcs_unregister.  The `pkcs' includes
+ *    the name of the PKCS and member functions for the algorithm.  Usually
+ *    this function is not called directly.  Instead, application can call
+ *    the silc_pkcs_register_default to register all PKCSs that are
+ *    builtin the sources.  Returns FALSE on error.
  *
  ***/
-SilcUInt32 silc_pkcs_get_key_len(SilcPKCS self);
+SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_name
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister
  *
  * SYNOPSIS
  *
- *    const char *silc_pkcs_get_name(SilcPKCS pkcs);
+ *    SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
  *
  * DESCRIPTION
  *
- *    Returns PKCS name.
+ *    Unregister a PKCS from the crypto library. Returns FALSE on error.
  *
  ***/
-const char *silc_pkcs_get_name(SilcPKCS pkcs);
+SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_public_key
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_register
  *
  * SYNOPSIS
  *
- *    unsigned char *silc_pkcs_get_public_key(SilcPKCS pkcs, SilcUInt32 *len);
+ *    SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
  *
  * DESCRIPTION
  *
- *    Returns SILC style public key.  The caller must free the returned
- *    data.
+ *    Registers a new PKCS Algorithm into crypto library.  This function
+ *    is used at the initialization of an application.  All registered PKCS
+*     algorithms should be unregistered with silc_pkcs_unregister.
  *
  ***/
-unsigned char *silc_pkcs_get_public_key(SilcPKCS pkcs, SilcUInt32 *len);
+SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_private_key
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_unregister
  *
  * SYNOPSIS
  *
- *    unsigned char *silc_pkcs_get_private_key(SilcPKCS pkcs,
- *                                             SilcUInt32 *len);
+ *    SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
  *
  * DESCRIPTION
  *
- *    Returns SILC style private key.  The caller must free the returned
- *    data and SHOULD zero the memory area before freeing.
+ *    Unregister a PKCS from the crypto library. Returns FALSE on error.
  *
  ***/
-unsigned char *silc_pkcs_get_private_key(SilcPKCS pkcs, SilcUInt32 *len);
+SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_set
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_register_default
  *
  * SYNOPSIS
  *
- *    SilcUInt32 silc_pkcs_public_key_set(SilcPKCS pkcs,
- *                                        SilcPublicKey public_key);
+ *    SilcBool silc_pkcs_register_default(void);
  *
  * DESCRIPTION
  *
- *    Sets public key from SilcPublicKey. Returns the length of the key.
+ *    Registers all the default PKCS (all builtin PKCS) and PKCS algorithms.
+ *    The application may use this to register the default PKCS if specific
+ *    PKCS in any specific order is not wanted.  Returns FALSE on error.
  *
  ***/
-SilcUInt32 silc_pkcs_public_key_set(SilcPKCS pkcs, SilcPublicKey public_key);
+SilcBool silc_pkcs_register_default(void);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_data_set
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister_all
  *
  * SYNOPSIS
  *
- *    SilcUInt32 silc_pkcs_public_key_data_set(SilcPKCS pkcs,
- *                                             unsigned char *pk,
- *                                             SilcUInt32 pk_len);
+ *    SilcBool silc_pkcs_unregister_all(void);
  *
  * DESCRIPTION
  *
- *    Sets public key from data. Returns the length of the key.
+ *    Unregister all PKCS and PKCS algorithms. Returns FALSE on error.
  *
  ***/
-SilcUInt32 silc_pkcs_public_key_data_set(SilcPKCS pkcs, unsigned char *pk,
-                                        SilcUInt32 pk_len);
+SilcBool silc_pkcs_unregister_all(void);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_set
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_supported
  *
  * SYNOPSIS
  *
- *    SilcUInt32 silc_pkcs_private_key_set(SilcPKCS pkcs,
- *                                         SilcPrivateKey private_key);
+ *    char *silc_pkcs_get_supported(void);
  *
  * DESCRIPTION
  *
- *    Sets private key from SilcPrivateKey. Returns the length of the key.
+ *    Returns comma separated list of supported PKCS algorithms.
  *
  ***/
-SilcUInt32 silc_pkcs_private_key_set(SilcPKCS pkcs, SilcPrivateKey private_key);
+char *silc_pkcs_get_supported(void);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_data_set
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_pkcs
  *
  * SYNOPSIS
  *
- *    SilcUInt32 silc_pkcs_private_key_data_set(SilcPKCS pkcs,
- *                                              unsigned char *prv,
- *                                              SilcUInt32 prv_len);
+ *    const SilcPKCSObject *silc_pkcs_get_pkcs(SilcPKCSType type);
  *
  * DESCRIPTION
  *
- *    Sets private key from data. Returns the length of the key.
+ *    Finds PKCS context by the PKCS type.
  *
  ***/
-SilcUInt32 silc_pkcs_private_key_data_set(SilcPKCS pkcs, unsigned char *prv,
-                                         SilcUInt32 prv_len);
+const SilcPKCSObject *silc_pkcs_find_pkcs(SilcPKCSType type);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_encrypt
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_algorithm
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src,
- *                           SilcUInt32 src_len, unsigned char *dst,
- *                           SilcUInt32 *dst_len);
+ *    const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
+ *                                                      const char *scheme);
  *
  * DESCRIPTION
  *
- *    Encrypts. Returns FALSE on error.
+ *    Finds PKCS algorithm context by the algorithm name `algorithm' and
+ *    the algorithm scheme `scheme'.  The `scheme' may be NULL.
  *
  ***/
-bool silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
-                      unsigned char *dst, SilcUInt32 *dst_len);
+const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
+                                                 const char *scheme);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_decrypt
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_pkcs
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src,
- *                           SilcUInt32 src_len, unsigned char *dst,
- *                           SilcUInt32 *dst_len);
+ *    const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
  *
  * DESCRIPTION
  *
- *    Decrypts.  Returns FALSE on error.
+ *    Returns the PKCS object from `key', which may be SilcPublicKey or
+ *    SilcPrivateKey pointer.
  *
  ***/
-bool silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
-                      unsigned char *dst, SilcUInt32 *dst_len);
+const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_sign
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_algorithm
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src,
- *                        SilcUInt32 src_len, unsigned char *dst,
- *                        SilcUInt32 *dst_len);
+ *    const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
  *
  * DESCRIPTION
  *
- *    Generates signature.  Returns FALSE on error.
+ *    Returns the PKCS algorithm object from `key', which may be SilcPublicKey
+ *    or SilcPrivateKey pointer.
  *
  ***/
-bool silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
-                   unsigned char *dst, SilcUInt32 *dst_len);
+const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_verify
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_name
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature,
- *                          SilcUInt32 signature_len, unsigned char *data,
- *                          SilcUInt32 data_len);
+ *    const char *silc_pkcs_get_name(void *key);
  *
  * DESCRIPTION
  *
- *    Verifies signature.  Returns FALSE on error.
+ *    Returns PKCS algorithm name from the `key', which may be SilcPublicKey
+ *    or SilcPrivateKey pointer.
  *
  ***/
-bool silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature,
-                     SilcUInt32 signature_len, unsigned char *data,
-                     SilcUInt32 data_len);
+const char *silc_pkcs_get_name(void *key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_sign_with_hash
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_type
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
- *                                  unsigned char *src, SilcUInt32 src_len,
- *                                  unsigned char *dst, SilcUInt32 *dst_len);
+ *    SilcPKCSType silc_pkcs_get_type(void *key);
  *
  * DESCRIPTION
  *
- *    Generates signature with hash.  The hash is signed.  Returns FALSE on
- *    error.
+ *    Returns PKCS type from the `key', which may be SilcPublicKey or
+ *    SilcPrivateKey pointer.
  *
  ***/
-bool silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
-                             unsigned char *src, SilcUInt32 src_len,
-                             unsigned char *dst, SilcUInt32 *dst_len);
+SilcPKCSType silc_pkcs_get_type(void *key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_verify_with_hash
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_get_pkcs
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash,
- *                                    unsigned char *signature,
- *                                    SilcUInt32 signature_len,
- *                                    unsigned char *data,
- *                                    SilcUInt32 data_len);
+ *    void *silc_pkcs_public_key_get_pkcs(SilcPKCSType type,
+ *                                        SilcPublicKey public_key);
  *
  * DESCRIPTION
  *
- *    Verifies signature with hash.  The `data' is hashed and verified against
- *    the `signature'.  Returns FALSE on error.
- *
- ***/
-bool silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash,
-                               unsigned char *signature,
-                               SilcUInt32 signature_len,
-                               unsigned char *data,
-                               SilcUInt32 data_len);
-
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_encode_identifier
- *
- * SYNOPSIS
- *
- *    char *silc_pkcs_encode_identifier(char *username, char *host,
- *                                      char *realname, char *email,
- *                                      char *org, char *country);
- *
- * DESCRIPTION
+ *    Returns the internal PKCS `type' specific public key context from the
+ *    `public_key'.  The caller needs to explicitly type cast it to correct
+ *    type.  Returns NULL on error.
  *
- *    Encodes and returns SILC public key identifier. If some of the
- *    arguments is NULL those are not encoded into the identifier string.
- *    Protocol says that at least username and host must be provided.
+ *    For SILC_PKCS_SILC the returned context is SilcSILCPublicKey.
+ *    For SILC_PKCS_SSH2 the returned context is SilcSshPublicKey.
  *
  ***/
-char *silc_pkcs_encode_identifier(char *username, char *host, char *realname,
-                                 char *email, char *org, char *country);
+void *silc_pkcs_public_key_get_pkcs(SilcPKCSType type,
+                                   SilcPublicKey public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_decode_identifier
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_get_pkcs
  *
  * SYNOPSIS
  *
- *    SilcPublicKeyIdentifier silc_pkcs_decode_identifier(char *identifier);
+ *    void *silc_pkcs_private_key_get_pkcs(SilcPKCSType type,
+ *                                        SilcPublicKey public_key);
  *
  * DESCRIPTION
  *
- *    Decodes the provided `identifier' and returns allocated context for
- *    the identifier.
- *
- ***/
-SilcPublicKeyIdentifier silc_pkcs_decode_identifier(char *identifier);
-
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_free_identifier
- *
- * SYNOPSIS
- *
- *    void silc_pkcs_free_identifier(SilcPublicKeyIdentifier identifier);
- *
- * DESCRIPTION
+ *    Returns the internal PKCS `type' specific private key context from the
+ *    `private_key'.  The caller needs to explicitly type cast it to correct
+ *    type.  Returns NULL on error.
  *
- *    Frees decoded public key identifier context.  Call this to free the
- *    context returned by the silc_pkcs_decode_identifier.
+ *    For SILC_PKCS_SILC the returned context is SilcSILCPrivateKey.
+ *    For SILC_PKCS_SSH2 the returned context is SilcSshPrivateKey.
  *
  ***/
-void silc_pkcs_free_identifier(SilcPublicKeyIdentifier identifier);
+void *silc_pkcs_private_key_get_pkcs(SilcPKCSType type,
+                                    SilcPrivateKey private_key);
 
 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_alloc
  *
  * SYNOPSIS
  *
- *    SilcPublicKey silc_pkcs_public_key_alloc(const char *name,
- *                                             const char *identifier,
- *                                             const unsigned char *pk,
- *                                             SilcUInt32 pk_len);
+ *    SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
+ *                                        unsigned char *key,
+ *                                        SilcUInt32 key_len
+ *                                        SilcPublicKey *ret_public_key);
  *
  * DESCRIPTION
  *
- *    Allocates SILC style public key formed from sent arguments.  All data
- *    is duplicated.
+ *    Allocates SilcPublicKey of the type of `type' from the key data
+ *    `key' of length of `key_len' bytes.  Returns FALSE if the `key'
+ *    is malformed or unsupported public key type.  This function can be
+ *    used to create public key from any kind of PKCS public keys that
+ *    the implementation supports.
  *
  ***/
-SilcPublicKey silc_pkcs_public_key_alloc(const char *name,
-                                        const char *identifier,
-                                        const unsigned char *pk,
-                                        SilcUInt32 pk_len);
+SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
+                                   unsigned char *key,
+                                   SilcUInt32 key_len,
+                                   SilcPublicKey *ret_public_key);
 
 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_free
  *
@@ -661,302 +469,357 @@ SilcPublicKey silc_pkcs_public_key_alloc(const char *name,
  *
  * DESCRIPTION
  *
- *    Frees public key.
+ *    Frees the public key.  This will also automatically free the underlaying
+ *    PKCS specific public key.  All public keys allocated through the
+ *    PKCS API must be freed by calling this function.
  *
  ***/
 void silc_pkcs_public_key_free(SilcPublicKey public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_alloc
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_export
  *
  * SYNOPSIS
  *
- *    SilcPrivateKey silc_pkcs_private_key_alloc(const char *name,
- *                                               const unsigned char *prv,
- *                                               SilcUInt32 prv_len);
+ *    unsigned char *silc_pkcs_public_key_encode(SilcStack stack,
+ *                                               SilcPublicKey public_key,
+ *                                               SilcUInt32 *ret_len);
  *
  * DESCRIPTION
  *
- *    Allocates SILC private key formed from sent arguments.  All data is
- *    duplicated.
+ *    Encodes the `public_key' into a binary format and returns it.  Returns
+ *    NULL on error.  Caller must free the returned buffer.
+ *
+ *    If the `stack' is non-NULL the returned buffer is allocated from the
+ *    `stack'.  This call will consume `stack' so caller should push the stack
+ *    before calling and then later pop it.
  *
  ***/
-SilcPrivateKey silc_pkcs_private_key_alloc(const char *name,
-                                          const unsigned char *prv,
-                                          SilcUInt32 prv_len);
+unsigned char *silc_pkcs_public_key_encode(SilcStack stack,
+                                          SilcPublicKey public_key,
+                                          SilcUInt32 *ret_len);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_free
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_get_len
  *
  * SYNOPSIS
  *
- *    void silc_pkcs_private_key_free(SilcPrivateKey private_key);
+ *    SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
  *
  * DESCRIPTION
  *
- *    Frees private key.
+ *    Returns the key length in bits from the public key.
  *
  ***/
-void silc_pkcs_private_key_free(SilcPrivateKey private_key);
+SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_encode
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_compare
  *
  * SYNOPSIS
  *
- *    unsigned char *
- *    silc_pkcs_public_key_encode(SilcPublicKey public_key, SilcUInt32 *len);
+ *    SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1,
+ *                                          SilcPublicKey key2);
  *
  * DESCRIPTION
  *
- *    Encodes SILC style public key from SilcPublicKey.  Returns the encoded
- *    data.
+ *    Compares two public keys and returns TRUE if they are same key, and
+ *    FALSE if they are not same.
  *
  ***/
-unsigned char *
-silc_pkcs_public_key_encode(SilcPublicKey public_key, SilcUInt32 *len);
+SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_data_encode
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_copy
  *
  * SYNOPSIS
  *
- *    unsigned char *
- *    silc_pkcs_public_key_data_encode(unsigned char *pk, SilcUInt32 pk_len,
- *                                     char *pkcs, char *identifier,
- *                                     SilcUInt32 *len);
+ *    SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
  *
  * DESCRIPTION
  *
- *    Encodes SILC style public key.  Returns the encoded data.
+ *    Copies the public key indicated by `public_key' and returns new
+ *    allocated public key which is indentical to the `public_key'.
  *
  ***/
-unsigned char *
-silc_pkcs_public_key_data_encode(unsigned char *pk, SilcUInt32 pk_len,
-                                 char *pkcs, char *identifier,
-                                 SilcUInt32 *len);
+SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_decode
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_alloc
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_public_key_decode(unsigned char *data,
- *                                     SilcUInt32 data_len,
- *                                     SilcPublicKey *public_key);
+ *    SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
+ *                                         unsigned char *key,
+ *                                         SilcUInt32 key_len,
+ *                                         SilcPrivateKey *ret_private_key);
  *
  * DESCRIPTION
  *
- *    Decodes SILC style public key. Returns TRUE if the decoding was
- *    successful. Allocates new public key as well.
+ *    Allocates SilcPrivateKey of the type of `type' from the key data
+ *    `key' of length of `key_len' bytes.  Returns FALSE if the `key'
+ *    is malformed or unsupported private key type.
  *
  ***/
-bool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len,
-                                SilcPublicKey *public_key);
+SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
+                                    unsigned char *key,
+                                    SilcUInt32 key_len,
+                                    SilcPrivateKey *ret_private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_payload_encode
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_get_len
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_public_key_payload_encode(SilcPublicKey public_key);
+ *    SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
  *
  * DESCRIPTION
  *
- *    Encodes the Public Key Payload from the public key indicated by
- *    `public_key' of type of `pk_type'.  The type is SilcSKEPKType.
- *    Returns the encoded payload buffer.
+ *    Returns the key length in bits from the private key.
  *
  ***/
-SilcBuffer silc_pkcs_public_key_payload_encode(SilcPublicKey public_key);
+SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_payload_decode
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_free
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_public_key_payload_decode(unsigned char *data,
- *                                             SilcUInt32 data_len,
- *                                             SilcPublicKey *public_key);
+ *    void silc_pkcs_private_key_free(SilcPrivateKey private_key;
  *
  * DESCRIPTION
  *
- *    Decodes Public Key Payload from `data' of `data_len' bytes in length
- *    data buffer into `public_key' pointer.  Returns FALSE if the payload
- *    cannot be decoded.
+ *    Frees the public key.  This will also automatically free the underlaying
+ *    PKCS specific private key.  All private keys allocated through the
+ *    PKCS API must be freed by calling this function.
  *
  ***/
-bool silc_pkcs_public_key_payload_decode(unsigned char *data,
-                                        SilcUInt32 data_len,
-                                        SilcPublicKey *public_key);
+void silc_pkcs_private_key_free(SilcPrivateKey private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_compare
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_encrypt
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_public_key_compare(SilcPublicKey key1,
- *                                      SilcPublicKey key2);
+ *    SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
+ *                                         unsigned char *src,
+ *                                         SilcUInt32 src_len, SilcRng rng,
+ *                                         SilcPKCSEncryptCb encrypt_cb,
+ *                                         void *context);
  *
  * DESCRIPTION
  *
- *    Compares two public keys and returns TRUE if they are same key, and
- *    FALSE if they are not same.
+ *    Encrypts with the public key.  The `encrypt_cb' will be called to
+ *    deliver the encrypted data.  The encryption operation may be asynchronous
+ *    if the `public_key' is accelerated public key.  If this returns NULL
+ *    the asynchronous operation cannot be controlled.
  *
  ***/
-bool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2);
+SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
+                                    unsigned char *src,
+                                    SilcUInt32 src_len, SilcRng rng,
+                                    SilcPKCSEncryptCb encrypt_cb,
+                                    void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_copy
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_decrypt
  *
  * SYNOPSIS
  *
- *    SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
+ *    SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
+ *                                         unsigned char *src,
+ *                                         SilcUInt32 src_len,
+ *                                         SilcPKCSDecryptCb decrypt_cb,
+ *                                         void *context);
  *
  * DESCRIPTION
  *
- *    Copies the public key indicated by `public_key' and returns new allocated
- *    public key which is indentical to the `public_key'.
+ *    Decrypts with the private key.  The `decrypt_cb' will be called to
+ *    deliver the decrypted data.  The decryption operation may be asynchronous
+ *    if the `private_key' is accelerated private key.  If this returns NULL
+ *    the asynchronous operation cannot be controlled.
  *
  ***/
-SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
+SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
+                                    unsigned char *src, SilcUInt32 src_len,
+                                    SilcPKCSDecryptCb decrypt_cb,
+                                    void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_encode
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_sign
  *
  * SYNOPSIS
  *
- *    unsigned char *
- *    silc_pkcs_private_key_encode(SilcPrivateKey private_key,
- *                                 SilcUInt32 *len);
+ *    SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
+ *                                      unsigned char *src,
+ *                                      SilcUInt32 src_len,
+ *                                      SilcBool compute_hash,
+ *                                      SilcHash hash,
+ *                                      SilcRng rng,
+ *                                      SilcPKCSSignCb sign_cb,
+ *                                      void *context);
  *
  * DESCRIPTION
  *
- *    Encodes SILC private key from SilcPrivateKey.  Returns the encoded data.
+ *    Computes signature with the private key.  The `sign_cb' will be called
+ *    to deliver the signature data.  If `compute_hash' is TRUE the `hash'
+ *    will be used to compute a message digest over the `src'.  The `hash'
+ *    must always be valid.  The `rng' should always be provided.  The
+ *    signature operation may be asynchronous if the `private_key' is
+ *    accelerated private key.  If this returns NULL the asynchronous
+ *    operation cannot be controlled.
  *
  ***/
-unsigned char *
-silc_pkcs_private_key_encode(SilcPrivateKey private_key, SilcUInt32 *len);
+SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
+                                 unsigned char *src,
+                                 SilcUInt32 src_len,
+                                 SilcBool compute_hash,
+                                 SilcHash hash,
+                                 SilcRng rng,
+                                 SilcPKCSSignCb sign_cb,
+                                 void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_data_encode
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_verify
  *
  * SYNOPSIS
  *
- *    unsigned char *
- *    silc_pkcs_private_key_data_encode(unsigned char *prv, SilcUInt32 prv_len,
- *                                      char *pkcs, SilcUInt32 *len);
+ *    SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
+ *                                        unsigned char *signature,
+ *                                        SilcUInt32 signature_len,
+ *                                        unsigned char *data,
+ *                                        SilcUInt32 data_len,
+ *                                        SilcHash hash,
+ *                                        SilcPKCSVerifyCb verify_cb,
+ *                                        void *context);
  *
  * DESCRIPTION
  *
- *    Encodes SILC private key.  Returns the encoded data.
+ *    Verifies signature.  The `verify_cb' will be called to deliver the
+ *    result of the verification process.  The 'signature' is verified against
+ *    the 'data'.  If the `hash' is non-NULL then the `data' will hashed
+ *    before verification.  If the `hash' is NULL, then the hash algorithm
+ *    to be used is retrieved from the signature.  If it isn't present in the
+ *    signature the verification is done as is without hashing.  The `rng'
+ *    is usually not needed and may be NULL.  If this returns NULL the
+ *    asynchronous operation cannot be controlled.
  *
  ***/
-unsigned char *
-silc_pkcs_private_key_data_encode(unsigned char *prv, SilcUInt32 prv_len,
-                                 char *pkcs, SilcUInt32 *len);
+SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
+                                   unsigned char *signature,
+                                   SilcUInt32 signature_len,
+                                   unsigned char *data,
+                                   SilcUInt32 data_len,
+                                   SilcHash hash,
+                                   SilcPKCSVerifyCb verify_cb,
+                                   void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_decode
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_public_key
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_private_key_decode(unsigned char *data,
- *                                      SilcUInt32 data_len,
- *                                      SilcPrivateKey *private_key);
+ *    SilcBool silc_pkcs_load_public_key(const char *filename,
+ *                                       SilcPKCSType type,
+ *                                       SilcPublicKey *ret_public_key);
  *
  * DESCRIPTION
  *
- *    Decodes SILC style private key.  Returns TRUE if the decoding was
- *    successful.  Allocates new private key as well.
+ *    Loads public key from file and allocates new public key.  Returns TRUE
+ *    if loading was successful.  If `type' is SILC_PKSC_ANY this attempts
+ *    to automatically detect the public key type.  If `type' is some other
+ *    PKCS type, the key is expected to be of that type.
  *
  ***/
-bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
-                                 SilcPrivateKey *private_key);
+SilcBool silc_pkcs_load_public_key(const char *filename,
+                                  SilcPKCSType type,
+                                  SilcPublicKey *ret_public_key);
 
 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_public_key
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_save_public_key(const char *filename,
- *                                   SilcPublicKey public_key,
- *                                   SilcUInt32 encoding);
+ *    SilcBool silc_pkcs_save_public_key(const char *filename,
+ *                                       SilcPublicKey public_key,
+ *                                       SilcPKCSFileEncoding encoding);
  *
  * DESCRIPTION
  *
- *    Saves public key into file.  Returns FALSE on error.
+ *    Saves public key into file with specified encoding.  Returns FALSE
+ *    on error.
  *
  ***/
-bool silc_pkcs_save_public_key(const char *filename, SilcPublicKey public_key,
-                              SilcUInt32 encoding);
+SilcBool silc_pkcs_save_public_key(const char *filename,
+                                  SilcPublicKey public_key,
+                                  SilcPKCSFileEncoding encoding);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_public_key_data
+/****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_private_key
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_save_public_key_data(const char *filename,
- *                                        unsigned char *data,
- *                                        SilcUInt32 data_len,
- *                                        SilcUInt32 encoding);
+ *    SilcBool silc_pkcs_load_private_key(const char *filename,
+ *                                        const unsigned char *passphrase,
+ *                                        SilcUInt32 passphrase_len,
+ *                                        SilcPKCSType type,
+ *                                        SilcPrivateKey *ret_private_key);
  *
  * DESCRIPTION
  *
- *    Saves public key into file.  The public key is already encoded as
- *    data when calling this function.  Returns FALSE on error.
+ *    Loads private key from file and allocates new private key.  Returns TRUE
+ *    if loading was successful.  The `passphrase' is used as decryption
+ *    key of the private key file, in case it is encrypted.  If `type' is
+ *    SILC_PKSC_ANY this attempts to automatically detect the private key type.
+ *    If `type' is some other PKCS type, the key is expected to be of that
+ *    type.
  *
  ***/
-bool silc_pkcs_save_public_key_data(const char *filename, unsigned char *data,
-                                   SilcUInt32 data_len, SilcUInt32 encoding);
+SilcBool silc_pkcs_load_private_key(const char *filename,
+                                   const unsigned char *passphrase,
+                                   SilcUInt32 passphrase_len,
+                                   SilcPKCSType type,
+                                   SilcPrivateKey *ret_private_key);
 
 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_private_key
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_save_private_key(const char *filename,
- *                                    SilcPrivateKey private_key,
- *                                    unsigned char *passphrase,
- *                                    SilcUInt32 passphrase_len,
- *                                    SilcUInt32 encoding);
+ *    SilcBool silc_pkcs_save_private_key(const char *filename,
+ *                                        SilcPrivateKey private_key,
+ *                                        const unsigned char *passphrase,
+ *                                        SilcUInt32 passphrase_len,
+ *                                        SilcPKCSFileEncoding encoding,
+ *                                        SilcRng rng);
  *
  * DESCRIPTION
  *
  *    Saves private key into file.  The private key is encrypted into
- *    the file with the `passphrase' as a key.  The encryption algorithm
- *    is AES with 256 bit key in CBC mode.  Returns FALSE on error.
+ *    the file with the `passphrase' as a key, if PKCS supports encrypted
+ *    private keys.  Returns FALSE on error.
  *
  ***/
-bool silc_pkcs_save_private_key(const char *filename,
-                               SilcPrivateKey private_key,
-                               unsigned char *passphrase,
-                               SilcUInt32 passphrase_len,
-                               SilcUInt32 encoding);
+SilcBool silc_pkcs_save_private_key(const char *filename,
+                                   SilcPrivateKey private_key,
+                                   const unsigned char *passphrase,
+                                   SilcUInt32 passphrase_len,
+                                   SilcPKCSFileEncoding encoding,
+                                   SilcRng rng);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_public_key
+/****f* silccrypt/SilcPKCSAPI/silc_hash_public_key
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_load_public_key(const char *filename,
- *                                   SilcPublicKey *public_key,
- *                                   SilcUInt32 encoding);
+ *    SilcUInt32 silc_hash_public_key(void *key, void *user_context);
  *
  * DESCRIPTION
  *
- *    Loads public key from file and allocates new public key.  Returns TRUE
- *    if loading was successful.
+ *    An utility function for hashing public key for SilcHashTable.  Give
+ *    this as argument as the hash function for SilcHashTable.
  *
  ***/
-bool silc_pkcs_load_public_key(const char *filename, SilcPublicKey *public_key,
-                              SilcUInt32 encoding);
+SilcUInt32 silc_hash_public_key(void *key, void *user_context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_private_key
+/****f* silccrypt/SilcPKCSAPI/silc_hash_public_key_compare
  *
  * SYNOPSIS
  *
- *    bool silc_pkcs_load_private_key(const char *filename,
- *                                    SilcPrivateKey *private_key,
- *                                    unsigned char *passphrase,
- *                                    SilcUInt32 passphrase_len,
- *                                    SilcUInt32 encoding);
+ *    SilcBool silc_hash_public_key_compare(void *key1, void *key2,
+ *                                          void *user_context);
  *
  * DESCRIPTION
  *
- *    Loads private key from file and allocates new private key.  Returns TRUE
- *    if loading was successful.  The `passphrase' is used as decryption
- *    key of the private key file.
+ *    An utility function for comparing public keys for SilcHashTable.  Give
+ *    this as argument as the compare function for SilcHashTable.
  *
  ***/
-bool silc_pkcs_load_private_key(const char *filename,
-                               SilcPrivateKey *private_key,
-                               unsigned char *passphrase,
-                               SilcUInt32 passphrase_len,
-                               SilcUInt32 encoding);
+SilcBool silc_hash_public_key_compare(void *key1, void *key2,
+                                     void *user_context);
 
 #endif /* !SILCPKCS_H */