5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 /****h* silccrypt/SILC PKCS Interface
24 * SILC PKCS API provides generic interface for performing various
25 * public key cryptography related operations with different types of
26 * public and private keys. Support for loading and saving of different
27 * types of public key and private keys are also provided.
34 /* Forward declarations */
35 typedef struct SilcPKCSAlgorithmStruct SilcPKCSAlgorithm;
36 typedef struct SilcPKCSObjectStruct SilcPKCSObject;
38 /****d* silccrypt/SilcPKCSAPI/SilcPKCSType
42 * typedef enum { ... } SilcPKCSType;
46 * Supported public key cryptosystem types.
51 SILC_PKCS_SILC = 1, /* SILC PKCS */
52 SILC_PKCS_SSH2 = 2, /* SSH2 PKCS */
53 SILC_PKCS_X509V3 = 3, /* X.509v3 PKCS */
54 SILC_PKCS_OPENPGP = 4, /* OpenPGP PKCS */
55 SILC_PKCS_SPKI = 5, /* SPKI PKCS (not supported) */
60 /****s* silccrypt/SilcPKCSAPI/SilcPublicKey
64 * typedef struct { ... } *SilcPublicKey;
68 * This context represents any kind of PKCS public key. It can be
69 * allocated by silc_pkcs_public_key_alloc or silc_pkcs_load_public_key
70 * and is freed by the silc_pkcs_public_key_free. The PKCS specific
71 * public key context can be retrieved by calling
72 * silc_pkcs_public_key_get_pkcs.
76 typedef struct SilcPublicKeyStruct {
77 SilcPKCSObject *pkcs; /* PKCS */
78 const SilcPKCSAlgorithm *alg; /* PKCS algorithm */
79 void *public_key; /* PKCS specific public key */
83 /****s* silccrypt/SilcPKCSAPI/SilcPrivateKey
87 * typedef struct { ... } *SilcPrivateKey;
91 * This context represents any kind of PKCS private key. It can be
92 * allocated by silc_pkcs_private_key_alloc or more commonly by calling
93 * silc_pkcs_load_private_key. The PKCS specific key context can be
94 * retrieved by calling silc_pkcs_private_key_get_pkcs.
98 typedef struct SilcPrivateKeyStruct {
99 SilcPKCSObject *pkcs; /* PKCS */
100 const SilcPKCSAlgorithm *alg; /* PKCS algorithm */
101 void *private_key; /* PKCS specific private key */
105 /****d* silccrypt/SilcPKCSAPI/SilcPKCSFileEncoding
109 * typedef enum { ... } SilcPKCSType
113 * Public and private key file encoding types.
118 SILC_PKCS_FILE_BIN, /* Binary encoding */
119 SILC_PKCS_FILE_BASE64 /* Base64 encoding */
120 } SilcPKCSFileEncoding;
123 /****f* silccrypt/SilcPKCSAPI/SilcPKCSEncryptCb
127 * typedef void (*SilcPKCSEncryptCb)(SilcBool success,
128 * const unsigned char *encrypted,
129 * SilcUInt32 encrypted_len,
134 * Encryption callback. This callback is given as argument to the
135 * silc_pkcs_encrypt and the encrypted data is delivered to the caller
136 * in this callback. The `encrypted' is the encrypted data. If the
137 * `success' is FALSE the encryption operation failed.
140 typedef void (*SilcPKCSEncryptCb)(SilcBool success,
141 const unsigned char *encrypted,
142 SilcUInt32 encrypted_len,
145 /****f* silccrypt/SilcPKCSAPI/SilcPKCSDecryptCb
149 * typedef void (*SilcPKCSDecryptCb)(SilcBool success,
150 * const unsigned char *decrypted,
151 * SilcUInt32 decrypted_len,
156 * Decryption callback. This callback is given as argument to the
157 * silc_pkcs_decrypt and the decrypted data is delivered to the caller
158 * in this callback. The `decrypted' is the decrypted data. If the
159 * `success' is FALSE the decryption operation failed.
162 typedef void (*SilcPKCSDecryptCb)(SilcBool success,
163 const unsigned char *decrypted,
164 SilcUInt32 decrypted_len,
167 /****f* silccrypt/SilcPKCSAPI/SilcPKCSSignCb
171 * typedef void (*SilcPKCSSignCb)(SilcBool success,
172 * const unsigned char *signature,
173 * SilcUInt32 signature_len,
178 * Signature callback. This callback is given as argument to the
179 * silc_pkcs_sign and the digitally signed data is delivered to the caller
180 * in this callback. The `signature' is the signature data. If the
181 * `success' is FALSE the signature operation failed.
184 typedef void (*SilcPKCSSignCb)(SilcBool success,
185 const unsigned char *signature,
186 SilcUInt32 signature_len,
189 /****f* silccrypt/SilcPKCSAPI/SilcPKCSVerifyCb
193 * typedef void (*SilcPKCSVerifyCb)(SilcBool success, void *context);
197 * Verification callback. This callback is given as argument to the
198 * silc_pkcs_verify and the result of the signature verification is
199 * deliver to the caller in this callback. If the `success' is FALSE
200 * the signature verification failed.
203 typedef void (*SilcPKCSVerifyCb)(SilcBool success, void *context);
205 #include "silcpkcs_i.h"
207 /* Marks for all PKCS in. This can be used in silc_pkcs_unregister to
208 unregister all PKCS at once. */
209 #define SILC_ALL_PKCS ((SilcPKCSObject *)1)
210 #define SILC_ALL_PKCS_ALG ((SilcPKCSAlgorithm *)1)
212 /* Static lists of PKCS and PKCS algorithms. */
213 extern DLLAPI const SilcPKCSObject silc_default_pkcs[];
214 extern DLLAPI const SilcPKCSAlgorithm silc_default_pkcs_alg[];
218 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_register
222 * SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
226 * Registers a new PKCS into the crypto library. This function is used
227 * at the initialization of an application. All registered PKCSs
228 * should be unregistered with silc_pkcs_unregister. The `pkcs' includes
229 * the name of the PKCS and member functions for the algorithm. Usually
230 * this function is not called directly. Instead, application can call
231 * the silc_pkcs_register_default to register all PKCSs that are
232 * builtin the sources. Returns FALSE on error.
235 SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
237 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister
241 * SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
245 * Unregister a PKCS from the crypto library. Returns FALSE on error.
248 SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
250 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_register
254 * SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
258 * Registers a new PKCS Algorithm into crypto library. This function
259 * is used at the initialization of an application. All registered PKCS
260 * algorithms should be unregistered with silc_pkcs_unregister.
263 SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
265 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_unregister
269 * SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
273 * Unregister a PKCS from the crypto library. Returns FALSE on error.
276 SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
278 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_register_default
282 * SilcBool silc_pkcs_register_default(void);
286 * Registers all the default PKCS (all builtin PKCS) and PKCS algorithms.
287 * The application may use this to register the default PKCS if specific
288 * PKCS in any specific order is not wanted. Returns FALSE on error.
291 SilcBool silc_pkcs_register_default(void);
293 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister_all
297 * SilcBool silc_pkcs_unregister_all(void);
301 * Unregister all PKCS and PKCS algorithms. Returns FALSE on error.
304 SilcBool silc_pkcs_unregister_all(void);
306 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_supported
310 * char *silc_pkcs_get_supported(void);
314 * Returns comma separated list of supported PKCS algorithms.
317 char *silc_pkcs_get_supported(void);
319 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_pkcs
323 * const SilcPKCSObject *silc_pkcs_get_pkcs(SilcPKCSType type);
327 * Finds PKCS context by the PKCS type.
330 const SilcPKCSObject *silc_pkcs_find_pkcs(SilcPKCSType type);
332 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_algorithm
336 * const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
337 * const char *scheme);
341 * Finds PKCS algorithm context by the algorithm name `algorithm' and
342 * the algorithm scheme `scheme'. The `scheme' may be NULL.
345 const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
348 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_pkcs
352 * const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
356 * Returns the PKCS object from `key', which may be SilcPublicKey or
357 * SilcPrivateKey pointer.
360 const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
362 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_algorithm
366 * const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
370 * Returns the PKCS algorithm object from `key', which may be SilcPublicKey
371 * or SilcPrivateKey pointer.
374 const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
376 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_name
380 * const char *silc_pkcs_get_name(void *key);
384 * Returns PKCS algorithm name from the `key', which may be SilcPublicKey
385 * or SilcPrivateKey pointer.
388 const char *silc_pkcs_get_name(void *key);
390 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_type
394 * SilcPKCSType silc_pkcs_get_type(void *key);
398 * Returns PKCS type from the `key', which may be SilcPublicKey or
399 * SilcPrivateKey pointer.
402 SilcPKCSType silc_pkcs_get_type(void *key);
404 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_get_pkcs
408 * void *silc_pkcs_public_key_get_pkcs(SilcPKCSType type,
409 * SilcPublicKey public_key);
413 * Returns the internal PKCS `type' specific public key context from the
414 * `public_key'. The caller needs to explicitly type cast it to correct
415 * type. Returns NULL on error.
417 * For SILC_PKCS_SILC the returned context is SilcSILCPublicKey.
418 * For SILC_PKCS_SSH2 the returned context is SilcSshPublicKey.
421 void *silc_pkcs_public_key_get_pkcs(SilcPKCSType type,
422 SilcPublicKey public_key);
424 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_get_pkcs
428 * void *silc_pkcs_private_key_get_pkcs(SilcPKCSType type,
429 * SilcPublicKey public_key);
433 * Returns the internal PKCS `type' specific private key context from the
434 * `private_key'. The caller needs to explicitly type cast it to correct
435 * type. Returns NULL on error.
437 * For SILC_PKCS_SILC the returned context is SilcSILCPrivateKey.
438 * For SILC_PKCS_SSH2 the returned context is SilcSshPrivateKey.
441 void *silc_pkcs_private_key_get_pkcs(SilcPKCSType type,
442 SilcPrivateKey private_key);
444 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_alloc
448 * SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
449 * unsigned char *key,
451 * SilcPublicKey *ret_public_key);
455 * Allocates SilcPublicKey of the type of `type' from the key data
456 * `key' of length of `key_len' bytes. Returns FALSE if the `key'
457 * is malformed or unsupported public key type. This function can be
458 * used to create public key from any kind of PKCS public keys that
459 * the implementation supports.
462 SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
465 SilcPublicKey *ret_public_key);
467 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_free
471 * void silc_pkcs_public_key_free(SilcPublicKey public_key);
475 * Frees the public key. This will also automatically free the underlaying
476 * PKCS specific public key. All public keys allocated through the
477 * PKCS API must be freed by calling this function.
480 void silc_pkcs_public_key_free(SilcPublicKey public_key);
482 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_export
486 * unsigned char *silc_pkcs_public_key_encode(SilcStack stack,
487 * SilcPublicKey public_key,
488 * SilcUInt32 *ret_len);
492 * Encodes the `public_key' into a binary format and returns it. Returns
493 * NULL on error. Caller must free the returned buffer.
495 * If the `stack' is non-NULL the returned buffer is allocated from the
496 * `stack'. This call will consume `stack' so caller should push the stack
497 * before calling and then later pop it.
500 unsigned char *silc_pkcs_public_key_encode(SilcStack stack,
501 SilcPublicKey public_key,
502 SilcUInt32 *ret_len);
504 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_get_len
508 * SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
512 * Returns the key length in bits from the public key.
515 SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
517 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_compare
521 * SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1,
522 * SilcPublicKey key2);
526 * Compares two public keys and returns TRUE if they are same key, and
527 * FALSE if they are not same.
530 SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2);
532 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_copy
536 * SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
540 * Copies the public key indicated by `public_key' and returns new
541 * allocated public key which is indentical to the `public_key'.
544 SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
546 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_alloc
550 * SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
551 * unsigned char *key,
552 * SilcUInt32 key_len,
553 * SilcPrivateKey *ret_private_key);
557 * Allocates SilcPrivateKey of the type of `type' from the key data
558 * `key' of length of `key_len' bytes. Returns FALSE if the `key'
559 * is malformed or unsupported private key type.
561 * Usually this function is not needed. Typical application calls
562 * silc_pkcs_load_private_key instead.
565 SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
568 SilcPrivateKey *ret_private_key);
570 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_get_len
574 * SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
578 * Returns the key length in bits from the private key.
581 SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
583 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_free
587 * void silc_pkcs_private_key_free(SilcPrivateKey private_key;
591 * Frees the public key. This will also automatically free the underlaying
592 * PKCS specific private key. All private keys allocated through the
593 * PKCS API must be freed by calling this function.
596 void silc_pkcs_private_key_free(SilcPrivateKey private_key);
598 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_encrypt
602 * SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
603 * unsigned char *src,
604 * SilcUInt32 src_len, SilcRng rng,
605 * SilcPKCSEncryptCb encrypt_cb,
610 * Encrypts with the public key. The `encrypt_cb' will be called to
611 * deliver the encrypted data. The encryption operation may be asynchronous
612 * if the `public_key' is accelerated public key. If this returns NULL
613 * the asynchronous operation cannot be controlled.
616 SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
618 SilcUInt32 src_len, SilcRng rng,
619 SilcPKCSEncryptCb encrypt_cb,
622 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_decrypt
626 * SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
627 * unsigned char *src,
628 * SilcUInt32 src_len,
629 * SilcPKCSDecryptCb decrypt_cb,
634 * Decrypts with the private key. The `decrypt_cb' will be called to
635 * deliver the decrypted data. The decryption operation may be asynchronous
636 * if the `private_key' is accelerated private key. If this returns NULL
637 * the asynchronous operation cannot be controlled.
640 SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
641 unsigned char *src, SilcUInt32 src_len,
642 SilcPKCSDecryptCb decrypt_cb,
645 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_sign
649 * SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
650 * unsigned char *src,
651 * SilcUInt32 src_len,
652 * SilcBool compute_hash,
655 * SilcPKCSSignCb sign_cb,
660 * Computes signature with the private key. The `sign_cb' will be called
661 * to deliver the signature data. If `compute_hash' is TRUE the `hash'
662 * will be used to compute a message digest over the `src'. The `hash'
663 * must always be valid. The `rng' should always be provided. The
664 * signature operation may be asynchronous if the `private_key' is
665 * accelerated private key. If this returns NULL the asynchronous
666 * operation cannot be controlled.
669 SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
672 SilcBool compute_hash,
675 SilcPKCSSignCb sign_cb,
678 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_verify
682 * SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
683 * unsigned char *signature,
684 * SilcUInt32 signature_len,
685 * unsigned char *data,
686 * SilcUInt32 data_len,
688 * SilcPKCSVerifyCb verify_cb,
693 * Verifies signature. The `verify_cb' will be called to deliver the
694 * result of the verification process. The 'signature' is verified against
695 * the 'data'. If the `hash' is non-NULL then the `data' will hashed
696 * before verification. If the `hash' is NULL, then the hash algorithm
697 * to be used is retrieved from the signature. If it isn't present in the
698 * signature the verification is done as is without hashing. The `rng'
699 * is usually not needed and may be NULL. If this returns NULL the
700 * asynchronous operation cannot be controlled.
703 SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
704 unsigned char *signature,
705 SilcUInt32 signature_len,
709 SilcPKCSVerifyCb verify_cb,
712 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_public_key
716 * SilcBool silc_pkcs_load_public_key(const char *filename,
718 * SilcPublicKey *ret_public_key);
722 * Loads public key from file and allocates new public key. Returns TRUE
723 * if loading was successful. If `type' is SILC_PKSC_ANY this attempts
724 * to automatically detect the public key type. If `type' is some other
725 * PKCS type, the key is expected to be of that type.
728 SilcBool silc_pkcs_load_public_key(const char *filename,
730 SilcPublicKey *ret_public_key);
732 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_public_key
736 * SilcBool silc_pkcs_save_public_key(const char *filename,
737 * SilcPublicKey public_key,
738 * SilcPKCSFileEncoding encoding);
742 * Saves public key into file with specified encoding. Returns FALSE
746 SilcBool silc_pkcs_save_public_key(const char *filename,
747 SilcPublicKey public_key,
748 SilcPKCSFileEncoding encoding);
750 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_private_key
754 * SilcBool silc_pkcs_load_private_key(const char *filename,
755 * const unsigned char *passphrase,
756 * SilcUInt32 passphrase_len,
758 * SilcPrivateKey *ret_private_key);
762 * Loads private key from file and allocates new private key. Returns TRUE
763 * if loading was successful. The `passphrase' is used as decryption
764 * key of the private key file, in case it is encrypted. If `type' is
765 * SILC_PKSC_ANY this attempts to automatically detect the private key type.
766 * If `type' is some other PKCS type, the key is expected to be of that
770 SilcBool silc_pkcs_load_private_key(const char *filename,
771 const unsigned char *passphrase,
772 SilcUInt32 passphrase_len,
774 SilcPrivateKey *ret_private_key);
776 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_private_key
780 * SilcBool silc_pkcs_save_private_key(const char *filename,
781 * SilcPrivateKey private_key,
782 * const unsigned char *passphrase,
783 * SilcUInt32 passphrase_len,
784 * SilcPKCSFileEncoding encoding,
789 * Saves private key into file. The private key is encrypted into
790 * the file with the `passphrase' as a key, if PKCS supports encrypted
791 * private keys. Returns FALSE on error.
794 SilcBool silc_pkcs_save_private_key(const char *filename,
795 SilcPrivateKey private_key,
796 const unsigned char *passphrase,
797 SilcUInt32 passphrase_len,
798 SilcPKCSFileEncoding encoding,
801 /****f* silccrypt/SilcPKCSAPI/silc_hash_public_key
805 * SilcUInt32 silc_hash_public_key(void *key, void *user_context);
809 * An utility function for hashing public key for SilcHashTable. Give
810 * this as argument as the hash function for SilcHashTable.
813 SilcUInt32 silc_hash_public_key(void *key, void *user_context);
815 /****f* silccrypt/SilcPKCSAPI/silc_hash_public_key_compare
819 * SilcBool silc_hash_public_key_compare(void *key1, void *key2,
820 * void *user_context);
824 * An utility function for comparing public keys for SilcHashTable. Give
825 * this as argument as the compare function for SilcHashTable.
828 SilcBool silc_hash_public_key_compare(void *key1, void *key2,
831 #endif /* !SILCPKCS_H */