SILC Crypto Toolkit 1.2 Beta1
[crypto.git] / lib / silccrypt / silcpkcs.h
index 857824f440f37828849041148980137effbf6830..4355ce53c37c64189939cd8078a0f2819c4c0cc2 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2007 Pekka Riikonen
+  Copyright (C) 1997 - 2008 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
@@ -17,7 +17,7 @@
 
 */
 
-/****h* silccrypt/SILC PKCS Interface
+/****h* silccrypt/PKCS Interface
  *
  * DESCRIPTION
  *
  * public and private keys.  Support for loading and saving of different
  * types of public key and private keys are also provided.
  *
+ * This interface is used to perform operations with public keys and private
+ * keys but the interface cannot be used to generate new key pairs.  Instead,
+ * PKCS implementations provide functions to generate key pairs.  Call
+ * silc_pkcs_silc_generate_key to generate SILC protocol key pair.  Call
+ * silc_ssh_generate_key to generate SSH2 protocol key pair.  Call
+ * silc_pgp_generate_key to generate OpenPGP key pair.
+ *
+ * EXAMPLE
+ *
+ * // Load public and private keys
+ * SilcPublicKey public_key;
+ * SilcPrivateKey private_key;
+ *
+ * silc_pkcs_load_public_key("pubkey.pub", SILC_PKCS_ANY, &public_key);
+ * silc_pkcs_load_private_key("privkey, prv", passphrase, passphrase_len,
+ *                            SILC_PKCS_ANY, &public_key);
+ *
+ * // Compute signature
+ * unsigned char dst[2048];
+ * SilcUInt32 sig_len;
+ *
+ * silc_pkcs_sign(private_key, src, src_len, dst, sizeof(dst), &sig_len,
+ *               TRUE, NULL, rng);
+ *
+ * // Free keys
+ * silc_pkcs_public_key_free(public_key);
+ * silc_pkcs_private_key_free(private_key);
+ *
  ***/
 
 #ifndef SILCPKCS_H
 #define SILCPKCS_H
 
 /* Forward declarations */
+typedef struct SilcPKCSAlgorithmStruct SilcPKCSAlgorithm;
 typedef struct SilcPKCSObjectStruct SilcPKCSObject;
 
-/****d* silccrypt/SilcPKCSAPI/SilcPKCSType
+/****d* silccrypt/SilcPKCSType
  *
  * NAME
  *
@@ -48,14 +77,88 @@ typedef struct SilcPKCSObjectStruct SilcPKCSObject;
  */
 typedef enum {
   SILC_PKCS_SILC    = 1,       /* SILC PKCS */
-  SILC_PKCS_SSH2    = 2,       /* SSH2 PKCS (not supported) */
-  SILC_PKCS_X509V3  = 3,       /* X.509v3 PKCS (not supported) */
-  SILC_PKCS_OPENPGP = 4,       /* OpenPGP PKCS (not supported) */
+  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/SilcPublicKey
+/****d* silccrypt/PKCS-Algorithms
+ *
+ * NAME
+ *
+ *    PKCS Algorithms
+ *
+ * DESCRIPTION
+ *
+ *    Supported PKCS algorithm names.  These names can be given as argument
+ *    to silc_pkcs_find_algorithm.  See also SilcPKCSSchemes.
+ *
+ * SOURCE
+ */
+#define SILC_PKCS_ALG_RSA    "rsa"         /* RSA algorithm */
+#define SILC_PKCS_ALG_DSA    "dsa"        /* DSA algorithm */
+/***/
+
+/****d* silccrypt/PKCS-Schemes
+ *
+ * NAME
+ *
+ *    PKCS Algorithm Schemes
+ *
+ * DESCRIPTION
+ *
+ *    Supported PKCS algorithm scheme names.  Different algorithms can be
+ *    implemented in different ways to conform differnet standards and
+ *    protocols.  The scheme defines these ways.  The scheme is given as
+ *    argument to silc_pkcs_find_algorithm.
+ *
+ * SOURCE
+ */
+
+/* PKCS #1 version 2.x.  This performs RSASSA-PKCS-v1_5 and RSAES-PKCS-v1_5
+   with hash OID in the signature data (signature with appendix).  This can
+   be used with SILC_PKCS_ALG_RSA.  Default hash function used with
+   signatures is SHA-1. */
+#define SILC_PKCS_SCHEME_PKCS1          "pkcs1"
+
+/* PKCS #1 version 2.x.  Same as SILC_PKCS_SCHEME_PKCS1 but the hash OID
+   is not present in the signature data.  This can be used with
+   SILC_PKCS_ALG_RSA.  Default hash function used with signatures is SHA-1. */
+#define SILC_PKCS_SCHEME_PKCS1_NO_OID   "pkcs1-no-oid"
+
+/* The Digital Signature Standard, FIPS 186-3.  The latest DSS standard
+   version.  The key parameters and hash function used are derived
+   automatically by the key length and the signature length is variable.
+   This can be used with SILC_PKCS_ALG_DSA. */
+#define SILC_PKCS_SCHEME_DSS            "dss"
+
+/* The Digital Signature Standard, FIPS 186-2.  Same as the
+   SILC_PKCS_SCHEME_DSS but the signature length is always 160 bits and
+   hash function used is SHA-1.  This is the most widely used DSS version
+   (<= year 2008).  This can be used with SILC_PKCS_ALG_DSA.  This is
+   compatible with SILC_PKCS_ALG_DSS when verifying signatures, but cannot
+   necessarily create compatible signature. */
+#define SILC_PKCS_SCHEME_DSS_FIPS186_2  "dss-fips186-2"
+
+#ifdef SILC_DIST_SSH
+/* The SSH2 protocol scheme.  This can be used with SILC_PKCS_ALG_RSA and
+   SILC_PKCS_ALG_DSA.  When used the algorithms behave as defined in the
+   SSH2 protocol. */
+#define SILC_PKCS_SCHEME_SSH            "ssh"
+#endif /* SILC_DIST_SSH */
+
+#ifdef SILC_DIST_PGP
+/* The OpenPGP protocol scheme.  This can be used with SILC_PKCS_ALG_RSA and
+   SILC_PKCS_ALG_DSA.  When used the algorithms behave as defined in the
+   OpenPGP protocol. */
+#define SILC_PKCS_SCHEME_OPENPGP        "openpgp"
+#endif /* SILC_DIST_PGP */
+/***/
+
+/****s* silccrypt/SilcPublicKey
  *
  * NAME
  *
@@ -64,19 +167,21 @@ typedef enum {
  * DESCRIPTION
  *
  *    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_get_context.
+ *    allocated by silc_pkcs_public_key_alloc or silc_pkcs_load_public_key
+ *    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 {
-  const SilcPKCSObject *pkcs;  /* PKCS */
+typedef struct SilcPublicKeyStruct {
+  SilcPKCSObject *pkcs;                /* PKCS */
+  const SilcPKCSAlgorithm *alg;        /* PKCS algorithm */
   void *public_key;            /* PKCS specific public key */
 } *SilcPublicKey;
 /***/
 
-/****s* silccrypt/SilcPKCSAPI/SilcPrivateKey
+/****s* silccrypt/SilcPrivateKey
  *
  * NAME
  *
@@ -84,17 +189,21 @@ typedef struct {
  *
  * DESCRIPTION
  *
- *    This context represents any kind of PKCS private key.
+ *    This context represents any kind of PKCS private key.  It can be
+ *    allocated by silc_pkcs_private_key_alloc or more commonly by calling
+ *    silc_pkcs_load_private_key.  The PKCS specific key context can be
+ *    retrieved by calling silc_pkcs_private_key_get_pkcs.
  *
  * SOURCE
  */
-typedef struct {
-  const SilcPKCSObject *pkcs;  /* PKCS */
+typedef struct SilcPrivateKeyStruct {
+  SilcPKCSObject *pkcs;                /* PKCS */
+  const SilcPKCSAlgorithm *alg;        /* PKCS algorithm */
   void *private_key;           /* PKCS specific private key */
 } *SilcPrivateKey;
 /***/
 
-/****d* silccrypt/SilcPKCSAPI/SilcPKCSFileEncoding
+/****d* silccrypt/SilcPKCSFileEncoding
  *
  * NAME
  *
@@ -112,398 +221,281 @@ typedef enum {
 } SilcPKCSFileEncoding;
 /***/
 
-/* The PKCS Algorithm object to represent any PKCS algorithm. */
-typedef struct {
-  /* Algorithm name and scheme */
-  char *name;
-  char *scheme;
-
-  /* Supported hash functions, comma separated list */
-  char *hash;
-
-  /* Generate new key pair. Returns PKCS algorithm specific public key
-     and private key contexts. */
-  SilcBool (*generate_key)(SilcUInt32 keylen,
-                          SilcRng rng,
-                          void **ret_public_key,
-                          void **ret_private_key);
-
-  /* Public key routines. */
-  int (*import_public_key)(unsigned char *key,
-                          SilcUInt32 key_len,
-                          void **ret_public_key);
-  unsigned char *(*export_public_key)(void *public_key,
-                                     SilcUInt32 *ret_len);
-  SilcUInt32 (*public_key_bitlen)(void *public_key);
-  void *(*public_key_copy)(void *public_key);
-  SilcBool (*public_key_compare)(void *key1, void *key2);
-  void (*public_key_free)(void *public_key);
-
-  /* Private key routines */
-  int (*import_private_key)(unsigned char *key,
-                           SilcUInt32 key_len,
-                           void **ret_private_key);
-  unsigned char *(*export_private_key)(void *private_key,
-                                      SilcUInt32 *ret_len);
-  SilcUInt32 (*private_key_bitlen)(void *public_key);
-  void (*private_key_free)(void *private_key);
-
-  /* Encrypt and decrypt operations */
-  SilcBool (*encrypt)(void *public_key,
-                     unsigned char *src,
-                     SilcUInt32 src_len,
-                     unsigned char *dst,
-                     SilcUInt32 dst_size,
-                     SilcUInt32 *ret_dst_len,
-                     SilcRng rng);
-  SilcBool (*decrypt)(void *private_key,
-                     unsigned char *src,
-                     SilcUInt32 src_len,
-                     unsigned char *dst,
-                     SilcUInt32 dst_size,
-                     SilcUInt32 *ret_dst_len);
-
-  /* Signature and verification operations */
-  SilcBool (*sign)(void *private_key,
-                  unsigned char *src,
-                  SilcUInt32 src_len,
-                  unsigned char *signature,
-                  SilcUInt32 signature_size,
-                  SilcUInt32 *ret_signature_len,
-                  SilcBool compute_hash,
-                  SilcHash hash);
-  SilcBool (*verify)(void *public_key,
-                    unsigned char *signature,
-                    SilcUInt32 signature_len,
-                    unsigned char *data,
-                    SilcUInt32 data_len,
-                    SilcHash hash);
-} SilcPKCSAlgorithm;
-
-/* The PKCS (Public Key Cryptosystem) object to represent any PKCS. */
-struct SilcPKCSObjectStruct {
-  /* PKCS type */
-  SilcPKCSType type;
-
-  /* Public key routines */
-
-  /* Returns PKCS algorithm context from public key */
-  const SilcPKCSAlgorithm *(*get_algorithm)(void *public_key);
-
-  /* Imports from public key file */
-  SilcBool (*import_public_key_file)(unsigned char *filedata,
-                                    SilcUInt32 filedata_len,
-                                    SilcPKCSFileEncoding encoding,
-                                    void **ret_public_key);
-
-  /* Imports from public key binary data.  Returns the amount of bytes
-     imported from `key' or 0 on error. */
-  int (*import_public_key)(unsigned char *key,
-                          SilcUInt32 key_len,
-                          void **ret_public_key);
-
-  /* Exports public key to file */
-  unsigned char *(*export_public_key_file)(void *public_key,
-                                          SilcPKCSFileEncoding encoding,
-                                          SilcUInt32 *ret_len);
-
-  /* Export public key as binary data */
-  unsigned char *(*export_public_key)(void *public_key,
-                                     SilcUInt32 *ret_len);
-
-  /* Returns key length in bits */
-  SilcUInt32 (*public_key_bitlen)(void *public_key);
-
-  /* Copy public key */
-  void *(*public_key_copy)(void *public_key);
-
-  /* Compares public keys */
-  SilcBool (*public_key_compare)(void *key1, void *key2);
-
-  /* Free public key */
-  void (*public_key_free)(void *public_key);
-
-  /* Private key routines */
-
-  /* Imports from private key file */
-  SilcBool (*import_private_key_file)(unsigned char *filedata,
-                                     SilcUInt32 filedata_len,
-                                     const char *passphrase,
-                                     SilcUInt32 passphrase_len,
-                                     SilcPKCSFileEncoding encoding,
-                                     void **ret_private_key);
-
-  /* Imports from private key binary data.  Returns the amount of bytes
-     imported from `key' or 0 on error. */
-  int (*import_private_key)(unsigned char *key,
-                           SilcUInt32 key_len,
-                           void **ret_private_key);
-
-  /* Exports private key to file */
-  unsigned char *(*export_private_key_file)(void *private_key,
-                                           const char *passphrase,
-                                           SilcUInt32 passphrase_len,
-                                           SilcPKCSFileEncoding encoding,
-                                           SilcRng rng,
-                                           SilcUInt32 *ret_len);
-
-  /* Export private key as binary data */
-  unsigned char *(*export_private_key)(void *private_key,
-                                      SilcUInt32 *ret_len);
-
-  /* Returns key length in bits */
-  SilcUInt32 (*private_key_bitlen)(void *private_key);
-
-  /* Free private key */
-  void (*private_key_free)(void *private_key);
-
-  /* Encrypt and decrypt operations */
-  SilcBool (*encrypt)(void *public_key,
-                     unsigned char *src,
-                     SilcUInt32 src_len,
-                     unsigned char *dst,
-                     SilcUInt32 dst_size,
-                     SilcUInt32 *ret_dst_len,
-                     SilcRng rng);
-  SilcBool (*decrypt)(void *private_key,
-                     unsigned char *src,
-                     SilcUInt32 src_len,
-                     unsigned char *dst,
-                     SilcUInt32 dst_size,
-                     SilcUInt32 *ret_dst_len);
-
-  /* Signature and verification operations */
-  SilcBool (*sign)(void *private_key,
-                  unsigned char *src,
-                  SilcUInt32 src_len,
-                  unsigned char *signature,
-                  SilcUInt32 signature_size,
-                  SilcUInt32 *ret_signature_len,
-                  SilcBool compute_hash,
-                  SilcHash hash);
-  SilcBool (*verify)(void *public_key,
-                    unsigned char *signature,
-                    SilcUInt32 signature_len,
-                    unsigned char *data,
-                    SilcUInt32 data_len,
-                    SilcHash hash);
-};
-
-/* 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)
-
-/* Static lists of PKCS and PKCS algorithms. */
-extern DLLAPI const SilcPKCSObject silc_default_pkcs[];
-extern DLLAPI const SilcPKCSAlgorithm silc_default_pkcs_alg[];
-
-/* Prototypes */
-
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_register
+/****f* silccrypt/SilcPKCSEncryptCb
  *
  * SYNOPSIS
  *
- *    SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
+ *    typedef void (*SilcPKCSEncryptCb)(SilcBool success,
+ *                                      const unsigned char *encrypted,
+ *                                      SilcUInt32 encrypted_len,
+ *                                      void *context);
  *
  * 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.
+ *    Encryption callback.  This callback is given as argument to the
+ *    silc_pkcs_encrypt_async 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.
  *
  ***/
-SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
+typedef void (*SilcPKCSEncryptCb)(SilcBool success,
+                                 const unsigned char *encrypted,
+                                 SilcUInt32 encrypted_len,
+                                 void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister
+/****f* silccrypt/SilcPKCSDecryptCb
  *
  * SYNOPSIS
  *
- *    SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
+ *    typedef void (*SilcPKCSDecryptCb)(SilcBool success,
+ *                                      const unsigned char *decrypted,
+ *                                      SilcUInt32 decrypted_len,
+ *                                      void *context);
  *
  * DESCRIPTION
  *
- *    Unregister a PKCS from the SILC. Returns FALSE on error.
+ *    Decryption callback.  This callback is given as argument to the
+ *    silc_pkcs_decrypt_async 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.
  *
  ***/
-SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
+typedef void (*SilcPKCSDecryptCb)(SilcBool success,
+                                 const unsigned char *decrypted,
+                                 SilcUInt32 decrypted_len,
+                                 void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_register
+/****f* silccrypt/SilcPKCSSignCb
  *
  * SYNOPSIS
  *
- *    SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
+ *    typedef void (*SilcPKCSSignCb)(SilcBool success,
+ *                                   const unsigned char *signature,
+ *                                   SilcUInt32 signature_len,
+ *                                   void *context);
  *
  * DESCRIPTION
  *
- *    Registers a new PKCS Algorithm into the SILC.  This function is used
- *    at the initialization of the SILC.  All registered PKCS algorithms
- *    should be unregistered with silc_pkcs_unregister.
+ *    Signature callback.  This callback is given as argument to the
+ *    silc_pkcs_sign_async 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.
  *
  ***/
-SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
+typedef void (*SilcPKCSSignCb)(SilcBool success,
+                              const unsigned char *signature,
+                              SilcUInt32 signature_len,
+                              void *context);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_unregister
+/****f* silccrypt/SilcPKCSVerifyCb
  *
  * SYNOPSIS
  *
- *    SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
+ *    typedef void (*SilcPKCSVerifyCb)(SilcBool success, void *context);
  *
  * DESCRIPTION
  *
- *    Unregister a PKCS from the SILC. Returns FALSE on error.
+ *    Verification callback.  This callback is given as argument to the
+ *    silc_pkcs_verify_async and the result of the signature verification is
+ *    deliver to the caller in this callback.  If the `success' is FALSE
+ *    the signature verification failed.
  *
  ***/
-SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
+typedef void (*SilcPKCSVerifyCb)(SilcBool success, void *context);
+
+#include "silcpkcs_i.h"
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_register_default
+/* 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)
+
+/* Static lists of PKCS and PKCS algorithms. */
+extern DLLAPI const SilcPKCSObject silc_default_pkcs[];
+extern DLLAPI const SilcPKCSAlgorithm silc_default_pkcs_alg[];
+
+/* Prototypes */
+
+/****f* silccrypt/silc_pkcs_register
  *
  * SYNOPSIS
  *
- *    SilcBool silc_pkcs_register_default(void);
+ *    SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
  *
  * DESCRIPTION
  *
- *    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.
+ *    Registers a new PKCS into the crypto library.  This function can be
+ *    used at the initialization of an application.  All registered PKCSs
+ *    should be unregistered with silc_pkcs_unregister.  Usually this
+ *    function is not needed.  The default PKCSs  are automatically
+ *    registered.  This can be used to change the order of the registered
+ *    PKCSs by re-registering them in desired order, or add new PKCSs.
+ *    Returns FALSE on error.
  *
  ***/
-SilcBool silc_pkcs_register_default(void);
+SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister_all
+/****f* silccrypt/silc_pkcs_unregister
  *
  * SYNOPSIS
  *
- *    SilcBool silc_pkcs_unregister_all(void);
+ *    SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
  *
  * DESCRIPTION
  *
- *    Unregister all PKCS and PKCS algorithms. Returns FALSE on error.
+ *    Unregister a PKCS from the crypto library. Returns FALSE on error.
  *
  ***/
-SilcBool silc_pkcs_unregister_all(void);
+SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_supported
+/****f* silccrypt/silc_pkcs_algorithm_register
  *
  * SYNOPSIS
  *
- *    char *silc_pkcs_get_supported(void);
+ *    SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
  *
  * DESCRIPTION
  *
- *    Returns comma separated list of supported PKCS algorithms.
+ *    Registers a new PKCS Algorithm into crypto library.  This function
+ *    can be used at the initialization of an application.  All registered
+ *    PKCS algorithms should be unregistered with silc_pkcs_unregister.
  *
  ***/
-char *silc_pkcs_get_supported(void);
+SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_pkcs
+/****f* silccrypt/silc_pkcs_algorithm_unregister
  *
  * SYNOPSIS
  *
- *    const SilcPKCSObject *silc_pkcs_get_pkcs(SilcPKCSType type);
+ *    SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
  *
  * DESCRIPTION
  *
- *    Finds PKCS context by the PKCS type.
+ *    Unregister a PKCS from the crypto library. Returns FALSE on error.
  *
  ***/
-const SilcPKCSObject *silc_pkcs_find_pkcs(SilcPKCSType type);
+SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_algorithm
+/****f* silccrypt/silc_pkcs_register_default
  *
  * SYNOPSIS
  *
- *    const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
- *                                                      const char *scheme);
+ *    SilcBool silc_pkcs_register_default(void);
  *
  * DESCRIPTION
  *
- *    Finds PKCS algorithm context by the algorithm name `algorithm' and
- *    the algorithm scheme `scheme'.  The `scheme' may be NULL.
+ *    Registers all the default PKCS (all builtin PKCS) and PKCS algorithms.
+ *    Application need not call this directly.  By calling silc_crypto_init
+ *    this function is called.
  *
  ***/
-const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
-                                                 const char *scheme);
+SilcBool silc_pkcs_register_default(void);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_pkcs
+/****f* silccrypt/silc_pkcs_unregister_all
  *
  * SYNOPSIS
  *
- *    const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
+ *    SilcBool silc_pkcs_unregister_all(void);
  *
  * DESCRIPTION
  *
- *    Returns the PKCS object from `key', which may be SilcPublicKey or
- *    SilcPrivateKey pointer.
+ *    Unregister all PKCS and PKCS algorithms. Returns FALSE on error.
+ *    Application need not call this directly.  By calling silc_crypto_init
+ *    this function is called.
  *
  ***/
-const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
+SilcBool silc_pkcs_unregister_all(void);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_algorithm
+/****f* silccrypt/silc_pkcs_load_public_key
  *
  * SYNOPSIS
  *
- *    const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
+ *    SilcBool silc_pkcs_load_public_key(const char *filename,
+ *                                       SilcPKCSType type,
+ *                                       SilcPublicKey *ret_public_key);
  *
  * DESCRIPTION
  *
- *    Returns the PKCS algorithm object from `key', which may be SilcPublicKey
- *    or SilcPrivateKey pointer.
+ *    Loads public key from file and allocates new public key.  Returns TRUE
+ *    if loading was successful.  If `type' is SILC_PKCS_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.
  *
  ***/
-const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
+SilcBool silc_pkcs_load_public_key(const char *filename,
+                                  SilcPKCSType type,
+                                  SilcPublicKey *ret_public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_name
+/****f* silccrypt/silc_pkcs_save_public_key
  *
  * SYNOPSIS
  *
- *    const char *silc_pkcs_get_name(void *key);
+ *    SilcBool silc_pkcs_save_public_key(const char *filename,
+ *                                       SilcPublicKey public_key,
+ *                                       SilcPKCSFileEncoding encoding);
  *
  * DESCRIPTION
  *
- *    Returns PKCS algorithm name from the `key', which may be SilcPublicKey
- *    or SilcPrivateKey pointer.
+ *    Saves public key into file with specified encoding.  Returns FALSE
+ *    on error.
  *
  ***/
-const char *silc_pkcs_get_name(void *key);
+SilcBool silc_pkcs_save_public_key(const char *filename,
+                                  SilcPublicKey public_key,
+                                  SilcPKCSFileEncoding encoding);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_type
+/****f* silccrypt/silc_pkcs_load_private_key
  *
  * SYNOPSIS
  *
- *    SilcPKCSType silc_pkcs_get_type(void *key);
+ *    SilcBool silc_pkcs_load_private_key(const char *filename,
+ *                                        const unsigned char *passphrase,
+ *                                        SilcUInt32 passphrase_len,
+ *                                        SilcPKCSType type,
+ *                                        SilcPrivateKey *ret_private_key);
  *
  * DESCRIPTION
  *
- *    Returns PKCS type from the `key', which may be SilcPublicKey or
- *    SilcPrivateKey pointer.
+ *    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_PKCS_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.
  *
  ***/
-SilcPKCSType silc_pkcs_get_type(void *key);
+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_get_context
+/****f* silccrypt/silc_pkcs_save_private_key
  *
  * SYNOPSIS
  *
- *    void *silc_pkcs_get_context(SilcPKCSType type, SilcPublicKey public_key);
+ *    SilcBool silc_pkcs_save_private_key(const char *filename,
+ *                                        SilcPrivateKey private_key,
+ *                                        const unsigned char *passphrase,
+ *                                        SilcUInt32 passphrase_len,
+ *                                        SilcPKCSFileEncoding encoding,
+ *                                        SilcRng rng);
  *
  * 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.
- *
- *    For SILC_PKCS_SILC the returned context is SilcSILCPublicKey.
+ *    Saves private key into file.  The private key is encrypted into
+ *    the file with the `passphrase' as a key, if PKCS supports encrypted
+ *    private keys.  Returns FALSE on error.
  *
  ***/
-void *silc_pkcs_get_context(SilcPKCSType type, SilcPublicKey public_key);
+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_public_key_alloc
+/****f* silccrypt/silc_pkcs_public_key_alloc
  *
  * SYNOPSIS
  *
@@ -526,7 +518,7 @@ SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
                                    SilcUInt32 key_len,
                                    SilcPublicKey *ret_public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_free
+/****f* silccrypt/silc_pkcs_public_key_free
  *
  * SYNOPSIS
  *
@@ -534,16 +526,19 @@ SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
  *
  * DESCRIPTION
  *
- *    Frees the 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_public_key_export
+/****f* silccrypt/silc_pkcs_public_key_encode
  *
  * SYNOPSIS
  *
- *    unsigned char *silc_pkcs_public_key_encode(SilcPublicKey public_key,
+ *    unsigned char *silc_pkcs_public_key_encode(SilcStack stack,
+ *                                               SilcPublicKey public_key,
  *                                               SilcUInt32 *ret_len);
  *
  * DESCRIPTION
@@ -551,11 +546,16 @@ void silc_pkcs_public_key_free(SilcPublicKey public_key);
  *    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.
+ *
  ***/
-unsigned char *silc_pkcs_public_key_encode(SilcPublicKey public_key,
+unsigned char *silc_pkcs_public_key_encode(SilcStack stack,
+                                          SilcPublicKey public_key,
                                           SilcUInt32 *ret_len);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_get_len
+/****f* silccrypt/silc_pkcs_public_key_get_len
  *
  * SYNOPSIS
  *
@@ -568,7 +568,7 @@ unsigned char *silc_pkcs_public_key_encode(SilcPublicKey public_key,
  ***/
 SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_compare
+/****f* silccrypt/silc_pkcs_public_key_compare
  *
  * SYNOPSIS
  *
@@ -583,7 +583,7 @@ SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
  ***/
 SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_copy
+/****f* silccrypt/silc_pkcs_public_key_copy
  *
  * SYNOPSIS
  *
@@ -597,7 +597,7 @@ SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2);
  ***/
 SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_alloc
+/****f* silccrypt/silc_pkcs_private_key_alloc
  *
  * SYNOPSIS
  *
@@ -612,13 +612,16 @@ SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
  *    `key' of length of `key_len' bytes.  Returns FALSE if the `key'
  *    is malformed or unsupported private key type.
  *
+ *    Usually this function is not needed.  Typical application calls
+ *    silc_pkcs_load_private_key instead.
+ *
  ***/
 SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
                                     unsigned char *key,
                                     SilcUInt32 key_len,
                                     SilcPrivateKey *ret_private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_get_len
+/****f* silccrypt/silc_pkcs_private_key_get_len
  *
  * SYNOPSIS
  *
@@ -631,7 +634,7 @@ SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
  ***/
 SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_free
+/****f* silccrypt/silc_pkcs_private_key_free
  *
  * SYNOPSIS
  *
@@ -639,23 +642,31 @@ SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
  *
  * DESCRIPTION
  *
- *    Frees the private key.
+ *    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.
  *
  ***/
 void silc_pkcs_private_key_free(SilcPrivateKey private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_encrypt
+/****f* silccrypt/silc_pkcs_encrypt
  *
  * SYNOPSIS
  *
  *    SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
  *                               unsigned char *src, SilcUInt32 src_len,
  *                               unsigned char *dst, SilcUInt32 dst_size,
- *                               SilcUInt32 *dst_len);
+ *                               SilcUInt32 *dst_len, SilcRng rng);
  *
  * DESCRIPTION
  *
- *    Encrypts with the public key. Returns FALSE on error.
+ *    Encrypts with the public key.  Returns FALSE on error.  The length
+ *    the encrypted data is returned to `dst_len' if it is non-NULL.
+ *
+ *    This call cannot be used if `public_key' is accelerated.  All
+ *    accelerators are usually asynchronous and the function will return
+ *    before the encryption has been done.  In this case the
+ *    silc_pkcs_encrypt_async should be used.
  *
  ***/
 SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
@@ -663,7 +674,32 @@ SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
                           unsigned char *dst, SilcUInt32 dst_size,
                           SilcUInt32 *dst_len, SilcRng rng);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_decrypt
+/****f* silccrypt/silc_pkcs_encrypt_async
+ *
+ * SYNOPSIS
+ *
+ *    SilcAsyncOperation
+ *    silc_pkcs_encrypt_async(SilcPublicKey public_key,
+ *                            unsigned char *src,
+ *                            SilcUInt32 src_len, SilcRng rng,
+ *                            SilcPKCSEncryptCb encrypt_cb,
+ *                            void *context);
+ *
+ * DESCRIPTION
+ *
+ *    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.
+ *
+ ***/
+SilcAsyncOperation silc_pkcs_encrypt_async(SilcPublicKey public_key,
+                                          unsigned char *src,
+                                          SilcUInt32 src_len, SilcRng rng,
+                                          SilcPKCSEncryptCb encrypt_cb,
+                                          void *context);
+
+/****f* silccrypt/silc_pkcs_decrypt
  *
  * SYNOPSIS
  *
@@ -674,7 +710,13 @@ SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
  *
  * DESCRIPTION
  *
- *    Decrypts with the private key.  Returns FALSE on error.
+ *    Decrypts with the private key.  Returns FALSE on error.  The length
+ *    of the decrypted data is returned to `dst_len' if it is non-NULL.
+ *
+ *    This call cannot be used if `public_key' is accelerated.  All
+ *    accelerators are usually asynchronous and the function will return
+ *    before the decryption has been done.  In this case the
+ *    silc_pkcs_decrypt_async should be used.
  *
  ***/
 SilcBool silc_pkcs_decrypt(SilcPrivateKey private_key,
@@ -682,7 +724,32 @@ SilcBool silc_pkcs_decrypt(SilcPrivateKey private_key,
                           unsigned char *dst, SilcUInt32 dst_size,
                           SilcUInt32 *dst_len);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_sign
+/****f* silccrypt/silc_pkcs_decrypt_async
+ *
+ * SYNOPSIS
+ *
+ *    SilcAsyncOperation
+ *    silc_pkcs_decrypt_async(SilcPrivateKey private_key,
+ *                            unsigned char *src,
+ *                            SilcUInt32 src_len,
+ *                            SilcPKCSDecryptCb decrypt_cb,
+ *                            void *context);
+ *
+ * DESCRIPTION
+ *
+ *    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.
+ *
+ ***/
+SilcAsyncOperation
+silc_pkcs_decrypt_async(SilcPrivateKey private_key,
+                       unsigned char *src, SilcUInt32 src_len,
+                       SilcPKCSDecryptCb decrypt_cb,
+                       void *context);
+
+/****f* silccrypt/silc_pkcs_sign
  *
  * SYNOPSIS
  *
@@ -690,22 +757,62 @@ SilcBool silc_pkcs_decrypt(SilcPrivateKey private_key,
  *                            unsigned char *src, SilcUInt32 src_len,
  *                            unsigned char *dst, SilcUInt32 dst_size,
  *                            SilcUInt32 *dst_len, SilcBool compute_hash,
- *                            SilcHash hash);
+ *                            SilcHash hash, SilcRng rng);
  *
  * DESCRIPTION
  *
- *    Generates signature with the private key.  Returns FALSE on error.
- *    If `compute_hash' is TRUE the `hash' will be used to compute a
- *    digest over the `src'.  The `hash' must always be valid.
+ *    Computes signature with the private key.  If `compute_hash' is TRUE
+ *    the `hash' will be used to compute a message digest over the `src'.
+ *    The `hash' is NULL the default hash function is used.  The `rng'
+ *    should always be provided.  The length of the signature is returned
+ *    to `dst_len' is it is non-NULL.
+ *
+ *    This call cannot be used if `public_key' is accelerated.  All
+ *    accelerators are usually asynchronous and the function will return
+ *    before the signagture has been done.  In this case the
+ *    silc_pkcs_sign_async should be used.
  *
  ***/
 SilcBool silc_pkcs_sign(SilcPrivateKey private_key,
                        unsigned char *src, SilcUInt32 src_len,
                        unsigned char *dst, SilcUInt32 dst_size,
                        SilcUInt32 *dst_len, SilcBool compute_hash,
-                       SilcHash hash);
+                       SilcHash hash, SilcRng rng);
+
+/****f* silccrypt/silc_pkcs_sign_async
+ *
+ * SYNOPSIS
+ *
+ *    SilcAsyncOperation silc_pkcs_sign_async(SilcPrivateKey private_key,
+ *                                            unsigned char *src,
+ *                                            SilcUInt32 src_len,
+ *                                            SilcBool compute_hash,
+ *                                            SilcHash hash,
+ *                                            SilcRng rng,
+ *                                            SilcPKCSSignCb sign_cb,
+ *                                            void *context);
+ *
+ * DESCRIPTION
+ *
+ *    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'
+ *    is NULL the default hash function is used.  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.
+ *
+ ***/
+SilcAsyncOperation silc_pkcs_sign_async(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_verify
+/****f* silccrypt/silc_pkcs_verify
  *
  * SYNOPSIS
  *
@@ -713,102 +820,237 @@ SilcBool silc_pkcs_sign(SilcPrivateKey private_key,
  *                              unsigned char *signature,
  *                              SilcUInt32 signature_len,
  *                              unsigned char *data,
- *                              SilcUInt32 data_len, SilcHash hash);
+ *                              SilcUInt32 data_len,
+ *                              SilcBool compute_hash,
+ *                              SilcHash hash);
  *
  * DESCRIPTION
  *
- *    Verifies signature.  Returns FALSE on error.  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.
+ *    Verifies signature.  The 'signature' is verified against the 'data'.
+ *    If `compute_hash' hash is TRUE the `hash' will be used in verification.
+ *    If `hash' is NULL, the hash algorithm to be used is retrieved from the
+ *    signature.  If it isn't present in the signature the default hash
+ *    function is used.  The `rng' is usually not needed and may be NULL.
+ *
+ *    This call cannot be used if `public_key' is accelerated.  All
+ *    accelerators are usually asynchronous and the function will return
+ *    before the verification has been done.  In this case the
+ *    silc_pkcs_verify_async should be used.
  *
  ***/
 SilcBool silc_pkcs_verify(SilcPublicKey public_key,
                          unsigned char *signature,
                          SilcUInt32 signature_len,
                          unsigned char *data,
-                         SilcUInt32 data_len, SilcHash hash);
+                         SilcUInt32 data_len,
+                         SilcBool compute_hash,
+                         SilcHash hash);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_public_key
+/****f* silccrypt/silc_pkcs_verify_async
  *
  * SYNOPSIS
  *
- *    SilcBool silc_pkcs_load_public_key(const char *filename,
- *                                       SilcPublicKey *ret_public_key);
+ *    SilcAsyncOperation silc_pkcs_verify_async(SilcPublicKey public_key,
+ *                                              unsigned char *signature,
+ *                                              SilcUInt32 signature_len,
+ *                                              unsigned char *data,
+ *                                              SilcUInt32 data_len,
+ *                                              SilcBool compute_hash,
+ *                                              SilcHash hash,
+ *                                              SilcPKCSVerifyCb verify_cb,
+ *                                              void *context);
  *
  * DESCRIPTION
  *
- *    Loads public key from file and allocates new public key.  Returns TRUE
- *    if loading was successful.
+ *    Verifies signature.  The `verify_cb' will be called to deliver the
+ *    result of the verification process.  The 'signature' is verified against
+ *    the 'data'.  If `compute_hash' hash is TRUE the `hash' will be used in
+ *    verification.  If `hash' is NULL, the hash algorithm to be used is
+ *    retrieved from the signature.  If it isn't present in the signature the
+ *    default hash function is used.  The `rng' is usually not needed and
+ *    may be NULL.  If this returns NULL the asynchronous operation cannot
+ *    be controlled.
  *
  ***/
-SilcBool silc_pkcs_load_public_key(const char *filename,
-                                  SilcPublicKey *ret_public_key);
+SilcAsyncOperation silc_pkcs_verify_async(SilcPublicKey public_key,
+                                         unsigned char *signature,
+                                         SilcUInt32 signature_len,
+                                         unsigned char *data,
+                                         SilcUInt32 data_len,
+                                         SilcBool compute_hash,
+                                         SilcHash hash,
+                                         SilcPKCSVerifyCb verify_cb,
+                                         void *context);
+
+/****f* silccrypt/silc_pkcs_public_key_get_pkcs
+ *
+ * SYNOPSIS
+ *
+ *    void *silc_pkcs_public_key_get_pkcs(SilcPKCSType type,
+ *                                        SilcPublicKey public_key);
+ *
+ * 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.
+ *
+ *    For SILC_PKCS_SILC the returned context is SilcSILCPublicKey.
+ *    For SILC_PKCS_SSH2 the returned context is SilcSshPublicKey.
+ *
+ ***/
+void *silc_pkcs_public_key_get_pkcs(SilcPKCSType type,
+                                   SilcPublicKey public_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_public_key
+/****f* silccrypt/silc_pkcs_private_key_get_pkcs
  *
  * SYNOPSIS
  *
- *    SilcBool silc_pkcs_save_public_key(const char *filename,
- *                                       SilcPublicKey public_key,
- *                                       SilcPKCSFileEncoding encoding);
+ *    void *silc_pkcs_private_key_get_pkcs(SilcPKCSType type,
+ *                                        SilcPublicKey public_key);
  *
  * DESCRIPTION
  *
- *    Saves public key into file with specified encoding.  Returns FALSE
- *    on error.
+ *    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.
+ *
+ *    For SILC_PKCS_SILC the returned context is SilcSILCPrivateKey.
+ *    For SILC_PKCS_SSH2 the returned context is SilcSshPrivateKey.
  *
  ***/
-SilcBool silc_pkcs_save_public_key(const char *filename,
-                                  SilcPublicKey public_key,
-                                  SilcPKCSFileEncoding encoding);
+void *silc_pkcs_private_key_get_pkcs(SilcPKCSType type,
+                                    SilcPrivateKey private_key);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_private_key
+/****f* silccrypt/silc_pkcs_find_pkcs
  *
  * SYNOPSIS
  *
- *    SilcBool silc_pkcs_load_private_key(const char *filename,
- *                                        const unsigned char *passphrase,
- *                                        SilcUInt32 passphrase_len,
- *                                        SilcPrivateKey *ret_private_key);
+ *    const SilcPKCSObject *silc_pkcs_get_pkcs(SilcPKCSType type);
  *
  * 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, in case it is encrypted.
+ *    Finds PKCS context by the PKCS type.
  *
  ***/
-SilcBool silc_pkcs_load_private_key(const char *filename,
-                                   const unsigned char *passphrase,
-                                   SilcUInt32 passphrase_len,
-                                   SilcPrivateKey *ret_private_key);
+const SilcPKCSObject *silc_pkcs_find_pkcs(SilcPKCSType type);
 
-/****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_private_key
+/****f* silccrypt/silc_pkcs_find_algorithm
  *
  * SYNOPSIS
  *
- *    SilcBool silc_pkcs_save_private_key(const char *filename,
- *                                        SilcPrivateKey private_key,
- *                                        const unsigned char *passphrase,
- *                                        SilcUInt32 passphrase_len,
- *                                        SilcPKCSFileEncoding encoding,
- *                                        SilcRng rng);
+ *    const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
+ *                                                      const char *scheme);
  *
  * DESCRIPTION
  *
- *    Saves private key into file.  The private key is encrypted into
- *    the file with the `passphrase' as a key, if PKCS supports encrypted
- *    private keys.  Returns FALSE on error.
+ *    Finds PKCS algorithm context by the algorithm name `algorithm' and
+ *    the algorithm scheme `scheme'.  The `scheme' may be NULL.  Usually
+ *    this function is not needed unless you need low level access to the
+ *    algorithm implementations.  Usually this is used when implementing
+ *    support to new PKCS type.
  *
  ***/
-SilcBool silc_pkcs_save_private_key(const char *filename,
-                                   SilcPrivateKey private_key,
-                                   const unsigned char *passphrase,
-                                   SilcUInt32 passphrase_len,
-                                   SilcPKCSFileEncoding encoding,
-                                   SilcRng rng);
+const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
+                                                 const char *scheme);
+
+/****f* silccrypt/silc_pkcs_get_pkcs
+ *
+ * SYNOPSIS
+ *
+ *    const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
+ *
+ * DESCRIPTION
+ *
+ *    Returns the PKCS object from `key', which may be SilcPublicKey or
+ *    SilcPrivateKey pointer.
+ *
+ ***/
+const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
+
+/****f* silccrypt/silc_pkcs_get_algorithm
+ *
+ * SYNOPSIS
+ *
+ *    const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
+ *
+ * DESCRIPTION
+ *
+ *    Returns the PKCS algorithm object from `key', which may be SilcPublicKey
+ *    or SilcPrivateKey pointer.
+ *
+ ***/
+const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
+
+/****f* silccrypt/silc_pkcs_get_name
+ *
+ * SYNOPSIS
+ *
+ *    const char *silc_pkcs_get_name(void *key);
+ *
+ * DESCRIPTION
+ *
+ *    Returns PKCS algorithm name from the `key', which may be SilcPublicKey
+ *    or SilcPrivateKey pointer.
+ *
+ ***/
+const char *silc_pkcs_get_name(void *key);
+
+/****f* silccrypt/silc_pkcs_get_type
+ *
+ * SYNOPSIS
+ *
+ *    SilcPKCSType silc_pkcs_get_type(void *key);
+ *
+ * DESCRIPTION
+ *
+ *    Returns PKCS type from the `key', which may be SilcPublicKey or
+ *    SilcPrivateKey pointer.
+ *
+ ***/
+SilcPKCSType silc_pkcs_get_type(void *key);
+
+/****f* silccrypt/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);
+
+/****f* silccrypt/silc_hash_public_key
+ *
+ * SYNOPSIS
+ *
+ *    SilcUInt32 silc_hash_public_key(void *key, void *user_context);
+ *
+ * DESCRIPTION
+ *
+ *    An utility function for hashing public key for SilcHashTable.  Give
+ *    this as argument as the hash function for SilcHashTable.
+ *
+ ***/
+SilcUInt32 silc_hash_public_key(void *key, void *user_context);
+
+/****f* silccrypt/silc_hash_public_key_compare
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool silc_hash_public_key_compare(void *key1, void *key2,
+ *                                          void *user_context);
+ *
+ * DESCRIPTION
+ *
+ *    An utility function for comparing public keys for SilcHashTable.  Give
+ *    this as argument as the compare function for SilcHashTable.
+ *
+ ***/
+SilcBool silc_hash_public_key_compare(void *key1, void *key2,
+                                     void *user_context);
 
 #endif /* !SILCPKCS_H */