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 and is freed by the
70 * silc_pkcs_public_key_free. The PKCS specific public key context
71 * can be retrieved by calling silc_pkcs_public_key_get_pkcs.
75 typedef struct SilcPublicKeyStruct {
76 SilcPKCSObject *pkcs; /* PKCS */
77 const SilcPKCSAlgorithm *alg; /* PKCS algorithm */
78 void *public_key; /* PKCS specific public key */
82 /****s* silccrypt/SilcPKCSAPI/SilcPrivateKey
86 * typedef struct { ... } *SilcPrivateKey;
90 * This context represents any kind of PKCS private key. The PKCS specific
91 * key context can be retrieved by calling silc_pkcs_private_key_get_pkcs.
95 typedef struct SilcPrivateKeyStruct {
96 SilcPKCSObject *pkcs; /* PKCS */
97 const SilcPKCSAlgorithm *alg; /* PKCS algorithm */
98 void *private_key; /* PKCS specific private key */
102 /****d* silccrypt/SilcPKCSAPI/SilcPKCSFileEncoding
106 * typedef enum { ... } SilcPKCSType
110 * Public and private key file encoding types.
115 SILC_PKCS_FILE_BIN, /* Binary encoding */
116 SILC_PKCS_FILE_BASE64 /* Base64 encoding */
117 } SilcPKCSFileEncoding;
120 /****f* silccrypt/SilcPKCSAPI/SilcPKCSEncryptCb
124 * typedef void (*SilcPKCSEncryptCb)(SilcBool success,
125 * const unsigned char *encrypted,
126 * SilcUInt32 encrypted_len,
131 * Encryption callback. This callback is given as argument to the
132 * silc_pkcs_encrypt and the encrypted data is delivered to the caller
133 * in this callback. The `encrypted' is the encrypted data. If the
134 * `success' is FALSE the encryption operation failed.
137 typedef void (*SilcPKCSEncryptCb)(SilcBool success,
138 const unsigned char *encrypted,
139 SilcUInt32 encrypted_len,
142 /****f* silccrypt/SilcPKCSAPI/SilcPKCSDecryptCb
146 * typedef void (*SilcPKCSDecryptCb)(SilcBool success,
147 * const unsigned char *decrypted,
148 * SilcUInt32 decrypted_len,
153 * Decryption callback. This callback is given as argument to the
154 * silc_pkcs_decrypt and the decrypted data is delivered to the caller
155 * in this callback. The `decrypted' is the decrypted data. If the
156 * `success' is FALSE the decryption operation failed.
159 typedef void (*SilcPKCSDecryptCb)(SilcBool success,
160 const unsigned char *decrypted,
161 SilcUInt32 decrypted_len,
164 /****f* silccrypt/SilcPKCSAPI/SilcPKCSSignCb
168 * typedef void (*SilcPKCSSignCb)(SilcBool success,
169 * const unsigned char *signature,
170 * SilcUInt32 signature_len,
175 * Signature callback. This callback is given as argument to the
176 * silc_pkcs_sign and the digitally signed data is delivered to the caller
177 * in this callback. The `signature' is the signature data. If the
178 * `success' is FALSE the signature operation failed.
181 typedef void (*SilcPKCSSignCb)(SilcBool success,
182 const unsigned char *signature,
183 SilcUInt32 signature_len,
186 /****f* silccrypt/SilcPKCSAPI/SilcPKCSVerifyCb
190 * typedef void (*SilcPKCSVerifyCb)(SilcBool success, void *context);
194 * Verification callback. This callback is given as argument to the
195 * silc_pkcs_verify and the result of the signature verification is
196 * deliver to the caller in this callback. If the `success' is FALSE
197 * the signature verification failed.
200 typedef void (*SilcPKCSVerifyCb)(SilcBool success, void *context);
202 #include "silcpkcs_i.h"
204 /* Marks for all PKCS in. This can be used in silc_pkcs_unregister to
205 unregister all PKCS at once. */
206 #define SILC_ALL_PKCS ((SilcPKCSObject *)1)
207 #define SILC_ALL_PKCS_ALG ((SilcPKCSAlgorithm *)1)
209 /* Static lists of PKCS and PKCS algorithms. */
210 extern DLLAPI const SilcPKCSObject silc_default_pkcs[];
211 extern DLLAPI const SilcPKCSAlgorithm silc_default_pkcs_alg[];
215 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_register
219 * SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
223 * Registers a new PKCS into the crypto library. This function is used
224 * at the initialization of an application. All registered PKCSs
225 * should be unregistered with silc_pkcs_unregister. The `pkcs' includes
226 * the name of the PKCS and member functions for the algorithm. Usually
227 * this function is not called directly. Instead, application can call
228 * the silc_pkcs_register_default to register all PKCSs that are
229 * builtin the sources. Returns FALSE on error.
232 SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
234 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister
238 * SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
242 * Unregister a PKCS from the crypto library. Returns FALSE on error.
245 SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
247 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_register
251 * SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
255 * Registers a new PKCS Algorithm into crypto library. This function
256 * is used at the initialization of an application. All registered PKCS
257 * algorithms should be unregistered with silc_pkcs_unregister.
260 SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
262 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_unregister
266 * SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
270 * Unregister a PKCS from the crypto library. Returns FALSE on error.
273 SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
275 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_register_default
279 * SilcBool silc_pkcs_register_default(void);
283 * Registers all the default PKCS (all builtin PKCS) and PKCS algorithms.
284 * The application may use this to register the default PKCS if specific
285 * PKCS in any specific order is not wanted. Returns FALSE on error.
288 SilcBool silc_pkcs_register_default(void);
290 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister_all
294 * SilcBool silc_pkcs_unregister_all(void);
298 * Unregister all PKCS and PKCS algorithms. Returns FALSE on error.
301 SilcBool silc_pkcs_unregister_all(void);
303 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_supported
307 * char *silc_pkcs_get_supported(void);
311 * Returns comma separated list of supported PKCS algorithms.
314 char *silc_pkcs_get_supported(void);
316 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_pkcs
320 * const SilcPKCSObject *silc_pkcs_get_pkcs(SilcPKCSType type);
324 * Finds PKCS context by the PKCS type.
327 const SilcPKCSObject *silc_pkcs_find_pkcs(SilcPKCSType type);
329 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_algorithm
333 * const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
334 * const char *scheme);
338 * Finds PKCS algorithm context by the algorithm name `algorithm' and
339 * the algorithm scheme `scheme'. The `scheme' may be NULL.
342 const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
345 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_pkcs
349 * const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
353 * Returns the PKCS object from `key', which may be SilcPublicKey or
354 * SilcPrivateKey pointer.
357 const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
359 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_algorithm
363 * const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
367 * Returns the PKCS algorithm object from `key', which may be SilcPublicKey
368 * or SilcPrivateKey pointer.
371 const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
373 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_name
377 * const char *silc_pkcs_get_name(void *key);
381 * Returns PKCS algorithm name from the `key', which may be SilcPublicKey
382 * or SilcPrivateKey pointer.
385 const char *silc_pkcs_get_name(void *key);
387 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_type
391 * SilcPKCSType silc_pkcs_get_type(void *key);
395 * Returns PKCS type from the `key', which may be SilcPublicKey or
396 * SilcPrivateKey pointer.
399 SilcPKCSType silc_pkcs_get_type(void *key);
401 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_get_pkcs
405 * void *silc_pkcs_public_key_get_pkcs(SilcPKCSType type,
406 * SilcPublicKey public_key);
410 * Returns the internal PKCS `type' specific public key context from the
411 * `public_key'. The caller needs to explicitly type cast it to correct
412 * type. Returns NULL on error.
414 * For SILC_PKCS_SILC the returned context is SilcSILCPublicKey.
415 * For SILC_PKCS_SSH2 the returned context is SilcSshPublicKey.
418 void *silc_pkcs_public_key_get_pkcs(SilcPKCSType type,
419 SilcPublicKey public_key);
421 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_get_pkcs
425 * void *silc_pkcs_private_key_get_pkcs(SilcPKCSType type,
426 * SilcPublicKey public_key);
430 * Returns the internal PKCS `type' specific private key context from the
431 * `private_key'. The caller needs to explicitly type cast it to correct
432 * type. Returns NULL on error.
434 * For SILC_PKCS_SILC the returned context is SilcSILCPrivateKey.
435 * For SILC_PKCS_SSH2 the returned context is SilcSshPrivateKey.
438 void *silc_pkcs_private_key_get_pkcs(SilcPKCSType type,
439 SilcPrivateKey private_key);
441 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_alloc
445 * SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
446 * unsigned char *key,
448 * SilcPublicKey *ret_public_key);
452 * Allocates SilcPublicKey of the type of `type' from the key data
453 * `key' of length of `key_len' bytes. Returns FALSE if the `key'
454 * is malformed or unsupported public key type. This function can be
455 * used to create public key from any kind of PKCS public keys that
456 * the implementation supports.
459 SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
462 SilcPublicKey *ret_public_key);
464 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_free
468 * void silc_pkcs_public_key_free(SilcPublicKey public_key);
472 * Frees the public key. This will also automatically free the underlaying
473 * PKCS specific public key. All public keys allocated through the
474 * PKCS API must be freed by calling this function.
477 void silc_pkcs_public_key_free(SilcPublicKey public_key);
479 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_export
483 * unsigned char *silc_pkcs_public_key_encode(SilcStack stack,
484 * SilcPublicKey public_key,
485 * SilcUInt32 *ret_len);
489 * Encodes the `public_key' into a binary format and returns it. Returns
490 * NULL on error. Caller must free the returned buffer.
492 * If the `stack' is non-NULL the returned buffer is allocated from the
493 * `stack'. This call will consume `stack' so caller should push the stack
494 * before calling and then later pop it.
497 unsigned char *silc_pkcs_public_key_encode(SilcStack stack,
498 SilcPublicKey public_key,
499 SilcUInt32 *ret_len);
501 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_get_len
505 * SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
509 * Returns the key length in bits from the public key.
512 SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
514 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_compare
518 * SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1,
519 * SilcPublicKey key2);
523 * Compares two public keys and returns TRUE if they are same key, and
524 * FALSE if they are not same.
527 SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2);
529 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_copy
533 * SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
537 * Copies the public key indicated by `public_key' and returns new
538 * allocated public key which is indentical to the `public_key'.
541 SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
543 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_alloc
547 * SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
548 * unsigned char *key,
549 * SilcUInt32 key_len,
550 * SilcPrivateKey *ret_private_key);
554 * Allocates SilcPrivateKey of the type of `type' from the key data
555 * `key' of length of `key_len' bytes. Returns FALSE if the `key'
556 * is malformed or unsupported private key type.
559 SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
562 SilcPrivateKey *ret_private_key);
564 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_get_len
568 * SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
572 * Returns the key length in bits from the private key.
575 SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
577 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_free
581 * void silc_pkcs_private_key_free(SilcPrivateKey private_key;
585 * Frees the public key. This will also automatically free the underlaying
586 * PKCS specific private key. All private keys allocated through the
587 * PKCS API must be freed by calling this function.
590 void silc_pkcs_private_key_free(SilcPrivateKey private_key);
592 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_encrypt
596 * SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
597 * unsigned char *src,
598 * SilcUInt32 src_len, SilcRng rng,
599 * SilcPKCSEncryptCb encrypt_cb,
604 * Encrypts with the public key. The `encrypt_cb' will be called to
605 * deliver the encrypted data. The encryption operation may be asynchronous
606 * if the `public_key' is accelerated public key. If this returns NULL
607 * the asynchronous operation cannot be controlled.
610 SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
612 SilcUInt32 src_len, SilcRng rng,
613 SilcPKCSEncryptCb encrypt_cb,
616 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_decrypt
620 * SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
621 * unsigned char *src,
622 * SilcUInt32 src_len,
623 * SilcPKCSDecryptCb decrypt_cb,
628 * Decrypts with the private key. The `decrypt_cb' will be called to
629 * deliver the decrypted data. The decryption operation may be asynchronous
630 * if the `private_key' is accelerated private key. If this returns NULL
631 * the asynchronous operation cannot be controlled.
634 SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
635 unsigned char *src, SilcUInt32 src_len,
636 SilcPKCSDecryptCb decrypt_cb,
639 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_sign
643 * SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
644 * unsigned char *src,
645 * SilcUInt32 src_len,
646 * SilcBool compute_hash,
649 * SilcPKCSSignCb sign_cb,
654 * Computes signature with the private key. The `sign_cb' will be called
655 * to deliver the signature data. If `compute_hash' is TRUE the `hash'
656 * will be used to compute a message digest over the `src'. The `hash'
657 * must always be valid. The `rng' should always be provided. The
658 * signature operation may be asynchronous if the `private_key' is
659 * accelerated private key. If this returns NULL the asynchronous
660 * operation cannot be controlled.
663 SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
666 SilcBool compute_hash,
669 SilcPKCSSignCb sign_cb,
672 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_verify
676 * SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
677 * unsigned char *signature,
678 * SilcUInt32 signature_len,
679 * unsigned char *data,
680 * SilcUInt32 data_len,
682 * SilcPKCSVerifyCb verify_cb,
687 * Verifies signature. The `verify_cb' will be called to deliver the
688 * result of the verification process. The 'signature' is verified against
689 * the 'data'. If the `hash' is non-NULL then the `data' will hashed
690 * before verification. If the `hash' is NULL, then the hash algorithm
691 * to be used is retrieved from the signature. If it isn't present in the
692 * signature the verification is done as is without hashing. The `rng'
693 * is usually not needed and may be NULL. If this returns NULL the
694 * asynchronous operation cannot be controlled.
697 SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
698 unsigned char *signature,
699 SilcUInt32 signature_len,
703 SilcPKCSVerifyCb verify_cb,
706 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_public_key
710 * SilcBool silc_pkcs_load_public_key(const char *filename,
712 * SilcPublicKey *ret_public_key);
716 * Loads public key from file and allocates new public key. Returns TRUE
717 * if loading was successful. If `type' is SILC_PKSC_ANY this attempts
718 * to automatically detect the public key type. If `type' is some other
719 * PKCS type, the key is expected to be of that type.
722 SilcBool silc_pkcs_load_public_key(const char *filename,
724 SilcPublicKey *ret_public_key);
726 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_public_key
730 * SilcBool silc_pkcs_save_public_key(const char *filename,
731 * SilcPublicKey public_key,
732 * SilcPKCSFileEncoding encoding);
736 * Saves public key into file with specified encoding. Returns FALSE
740 SilcBool silc_pkcs_save_public_key(const char *filename,
741 SilcPublicKey public_key,
742 SilcPKCSFileEncoding encoding);
744 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_private_key
748 * SilcBool silc_pkcs_load_private_key(const char *filename,
749 * const unsigned char *passphrase,
750 * SilcUInt32 passphrase_len,
752 * SilcPrivateKey *ret_private_key);
756 * Loads private key from file and allocates new private key. Returns TRUE
757 * if loading was successful. The `passphrase' is used as decryption
758 * key of the private key file, in case it is encrypted. If `type' is
759 * SILC_PKSC_ANY this attempts to automatically detect the private key type.
760 * If `type' is some other PKCS type, the key is expected to be of that
764 SilcBool silc_pkcs_load_private_key(const char *filename,
765 const unsigned char *passphrase,
766 SilcUInt32 passphrase_len,
768 SilcPrivateKey *ret_private_key);
770 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_private_key
774 * SilcBool silc_pkcs_save_private_key(const char *filename,
775 * SilcPrivateKey private_key,
776 * const unsigned char *passphrase,
777 * SilcUInt32 passphrase_len,
778 * SilcPKCSFileEncoding encoding,
783 * Saves private key into file. The private key is encrypted into
784 * the file with the `passphrase' as a key, if PKCS supports encrypted
785 * private keys. Returns FALSE on error.
788 SilcBool silc_pkcs_save_private_key(const char *filename,
789 SilcPrivateKey private_key,
790 const unsigned char *passphrase,
791 SilcUInt32 passphrase_len,
792 SilcPKCSFileEncoding encoding,
795 /****f* silccrypt/SilcPKCSAPI/silc_hash_public_key
799 * SilcUInt32 silc_hash_public_key(void *key, void *user_context);
803 * An utility function for hashing public key for SilcHashTable. Give
804 * this as argument as the hash function for SilcHashTable.
807 SilcUInt32 silc_hash_public_key(void *key, void *user_context);
809 /****f* silccrypt/SilcPKCSAPI/silc_hash_public_key_compare
813 * SilcBool silc_hash_public_key_compare(void *key1, void *key2,
814 * void *user_context);
818 * An utility function for comparing public keys for SilcHashTable. Give
819 * this as argument as the compare function for SilcHashTable.
822 SilcBool silc_hash_public_key_compare(void *key1, void *key2,
825 #endif /* !SILCPKCS_H */