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 SilcPKCSObjectStruct SilcPKCSObject;
37 /****d* silccrypt/SilcPKCSAPI/SilcPKCSType
41 * typedef enum { ... } SilcPKCSType;
45 * Supported public key cryptosystem types.
50 SILC_PKCS_SILC = 1, /* SILC PKCS */
51 SILC_PKCS_SSH2 = 2, /* SSH2 PKCS (not supported) */
52 SILC_PKCS_X509V3 = 3, /* X.509v3 PKCS (not supported) */
53 SILC_PKCS_OPENPGP = 4, /* OpenPGP PKCS (not supported) */
54 SILC_PKCS_SPKI = 5, /* SPKI PKCS (not supported) */
58 /****s* silccrypt/SilcPKCSAPI/SilcPublicKey
62 * typedef struct { ... } *SilcPublicKey;
66 * This context represents any kind of PKCS public key. It can be
67 * allocated by silc_pkcs_public_key_alloc and is freed by the
68 * silc_pkcs_public_key_free. The PKCS specific public key context
69 * can be retrieved by calling silc_pkcs_get_context.
73 typedef struct SilcPublicKeyStruct {
74 const SilcPKCSObject *pkcs; /* PKCS */
75 void *public_key; /* PKCS specific public key */
79 /****s* silccrypt/SilcPKCSAPI/SilcPrivateKey
83 * typedef struct { ... } *SilcPrivateKey;
87 * This context represents any kind of PKCS private key.
91 typedef struct SilcPrivateKeyStruct {
92 const SilcPKCSObject *pkcs; /* PKCS */
93 void *private_key; /* PKCS specific private key */
97 /****d* silccrypt/SilcPKCSAPI/SilcPKCSFileEncoding
101 * typedef enum { ... } SilcPKCSType
105 * Public and private key file encoding types.
110 SILC_PKCS_FILE_BIN, /* Binary encoding */
111 SILC_PKCS_FILE_BASE64 /* Base64 encoding */
112 } SilcPKCSFileEncoding;
115 /* The PKCS Algorithm object to represent any PKCS algorithm. */
117 /* Algorithm name and scheme */
121 /* Supported hash functions, comma separated list */
124 /* Generate new key pair. Returns PKCS algorithm specific public key
125 and private key contexts. */
126 SilcBool (*generate_key)(SilcUInt32 keylen,
128 void **ret_public_key,
129 void **ret_private_key);
131 /* Public key routines. */
132 int (*import_public_key)(unsigned char *key,
134 void **ret_public_key);
135 unsigned char *(*export_public_key)(void *public_key,
136 SilcUInt32 *ret_len);
137 SilcUInt32 (*public_key_bitlen)(void *public_key);
138 void *(*public_key_copy)(void *public_key);
139 SilcBool (*public_key_compare)(void *key1, void *key2);
140 void (*public_key_free)(void *public_key);
142 /* Private key routines */
143 int (*import_private_key)(unsigned char *key,
145 void **ret_private_key);
146 unsigned char *(*export_private_key)(void *private_key,
147 SilcUInt32 *ret_len);
148 SilcUInt32 (*private_key_bitlen)(void *public_key);
149 void (*private_key_free)(void *private_key);
151 /* Encrypt and decrypt operations */
152 SilcBool (*encrypt)(void *public_key,
157 SilcUInt32 *ret_dst_len,
159 SilcBool (*decrypt)(void *private_key,
164 SilcUInt32 *ret_dst_len);
166 /* Signature and verification operations */
167 SilcBool (*sign)(void *private_key,
170 unsigned char *signature,
171 SilcUInt32 signature_size,
172 SilcUInt32 *ret_signature_len,
173 SilcBool compute_hash,
175 SilcBool (*verify)(void *public_key,
176 unsigned char *signature,
177 SilcUInt32 signature_len,
183 /* The PKCS (Public Key Cryptosystem) object to represent any PKCS. */
184 struct SilcPKCSObjectStruct {
188 /* Public key routines */
190 /* Returns PKCS algorithm context from public key */
191 const SilcPKCSAlgorithm *(*get_algorithm)(void *public_key);
193 /* Imports from public key file */
194 SilcBool (*import_public_key_file)(unsigned char *filedata,
195 SilcUInt32 filedata_len,
196 SilcPKCSFileEncoding encoding,
197 void **ret_public_key);
199 /* Imports from public key binary data. Returns the amount of bytes
200 imported from `key' or 0 on error. */
201 int (*import_public_key)(unsigned char *key,
203 void **ret_public_key);
205 /* Exports public key to file */
206 unsigned char *(*export_public_key_file)(void *public_key,
207 SilcPKCSFileEncoding encoding,
208 SilcUInt32 *ret_len);
210 /* Export public key as binary data */
211 unsigned char *(*export_public_key)(void *public_key,
212 SilcUInt32 *ret_len);
214 /* Returns key length in bits */
215 SilcUInt32 (*public_key_bitlen)(void *public_key);
217 /* Copy public key */
218 void *(*public_key_copy)(void *public_key);
220 /* Compares public keys */
221 SilcBool (*public_key_compare)(void *key1, void *key2);
223 /* Free public key */
224 void (*public_key_free)(void *public_key);
226 /* Private key routines */
228 /* Imports from private key file */
229 SilcBool (*import_private_key_file)(unsigned char *filedata,
230 SilcUInt32 filedata_len,
231 const char *passphrase,
232 SilcUInt32 passphrase_len,
233 SilcPKCSFileEncoding encoding,
234 void **ret_private_key);
236 /* Imports from private key binary data. Returns the amount of bytes
237 imported from `key' or 0 on error. */
238 int (*import_private_key)(unsigned char *key,
240 void **ret_private_key);
242 /* Exports private key to file */
243 unsigned char *(*export_private_key_file)(void *private_key,
244 const char *passphrase,
245 SilcUInt32 passphrase_len,
246 SilcPKCSFileEncoding encoding,
248 SilcUInt32 *ret_len);
250 /* Export private key as binary data */
251 unsigned char *(*export_private_key)(void *private_key,
252 SilcUInt32 *ret_len);
254 /* Returns key length in bits */
255 SilcUInt32 (*private_key_bitlen)(void *private_key);
257 /* Free private key */
258 void (*private_key_free)(void *private_key);
260 /* Encrypt and decrypt operations */
261 SilcBool (*encrypt)(void *public_key,
266 SilcUInt32 *ret_dst_len,
268 SilcBool (*decrypt)(void *private_key,
273 SilcUInt32 *ret_dst_len);
275 /* Signature and verification operations */
276 SilcBool (*sign)(void *private_key,
279 unsigned char *signature,
280 SilcUInt32 signature_size,
281 SilcUInt32 *ret_signature_len,
282 SilcBool compute_hash,
284 SilcBool (*verify)(void *public_key,
285 unsigned char *signature,
286 SilcUInt32 signature_len,
292 /* Marks for all PKCS in. This can be used in silc_pkcs_unregister to
293 unregister all PKCS at once. */
294 #define SILC_ALL_PKCS ((SilcPKCSObject *)1)
295 #define SILC_ALL_PKCS_ALG ((SilcPKCSAlgorithm *)1)
297 /* Static lists of PKCS and PKCS algorithms. */
298 extern DLLAPI const SilcPKCSObject silc_default_pkcs[];
299 extern DLLAPI const SilcPKCSAlgorithm silc_default_pkcs_alg[];
303 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_register
307 * SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
311 * Registers a new PKCS into the crypto library. This function is used
312 * at the initialization of an application. All registered PKCSs
313 * should be unregistered with silc_pkcs_unregister. The `pkcs' includes
314 * the name of the PKCS and member functions for the algorithm. Usually
315 * this function is not called directly. Instead, application can call
316 * the silc_pkcs_register_default to register all PKCSs that are
317 * builtin the sources. Returns FALSE on error.
320 SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs);
322 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister
326 * SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
330 * Unregister a PKCS from the crypto library. Returns FALSE on error.
333 SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs);
335 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_register
339 * SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
343 * Registers a new PKCS Algorithm into crypto library. This function
344 * is used at the initialization of an application. All registered PKCS
345 * algorithms should be unregistered with silc_pkcs_unregister.
348 SilcBool silc_pkcs_algorithm_register(const SilcPKCSAlgorithm *pkcs);
350 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_algorithm_unregister
354 * SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
358 * Unregister a PKCS from the crypto library. Returns FALSE on error.
361 SilcBool silc_pkcs_algorithm_unregister(SilcPKCSAlgorithm *pkcs);
363 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_register_default
367 * SilcBool silc_pkcs_register_default(void);
371 * Registers all the default PKCS (all builtin PKCS) and PKCS algorithms.
372 * The application may use this to register the default PKCS if specific
373 * PKCS in any specific order is not wanted. Returns FALSE on error.
376 SilcBool silc_pkcs_register_default(void);
378 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_unregister_all
382 * SilcBool silc_pkcs_unregister_all(void);
386 * Unregister all PKCS and PKCS algorithms. Returns FALSE on error.
389 SilcBool silc_pkcs_unregister_all(void);
391 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_supported
395 * char *silc_pkcs_get_supported(void);
399 * Returns comma separated list of supported PKCS algorithms.
402 char *silc_pkcs_get_supported(void);
404 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_pkcs
408 * const SilcPKCSObject *silc_pkcs_get_pkcs(SilcPKCSType type);
412 * Finds PKCS context by the PKCS type.
415 const SilcPKCSObject *silc_pkcs_find_pkcs(SilcPKCSType type);
417 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_find_algorithm
421 * const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
422 * const char *scheme);
426 * Finds PKCS algorithm context by the algorithm name `algorithm' and
427 * the algorithm scheme `scheme'. The `scheme' may be NULL.
430 const SilcPKCSAlgorithm *silc_pkcs_find_algorithm(const char *algorithm,
433 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_pkcs
437 * const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
441 * Returns the PKCS object from `key', which may be SilcPublicKey or
442 * SilcPrivateKey pointer.
445 const SilcPKCSObject *silc_pkcs_get_pkcs(void *key);
447 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_algorithm
451 * const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
455 * Returns the PKCS algorithm object from `key', which may be SilcPublicKey
456 * or SilcPrivateKey pointer.
459 const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key);
461 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_name
465 * const char *silc_pkcs_get_name(void *key);
469 * Returns PKCS algorithm name from the `key', which may be SilcPublicKey
470 * or SilcPrivateKey pointer.
473 const char *silc_pkcs_get_name(void *key);
475 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_type
479 * SilcPKCSType silc_pkcs_get_type(void *key);
483 * Returns PKCS type from the `key', which may be SilcPublicKey or
484 * SilcPrivateKey pointer.
487 SilcPKCSType silc_pkcs_get_type(void *key);
489 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_get_context
493 * void *silc_pkcs_get_context(SilcPKCSType type, SilcPublicKey public_key);
497 * Returns the internal PKCS `type' specific public key context from the
498 * `public_key'. The caller needs to explicitly type cast it to correct
499 * type. Returns NULL on error.
501 * For SILC_PKCS_SILC the returned context is SilcSILCPublicKey.
504 void *silc_pkcs_get_context(SilcPKCSType type, SilcPublicKey public_key);
506 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_alloc
510 * SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
511 * unsigned char *key,
513 * SilcPublicKey *ret_public_key);
517 * Allocates SilcPublicKey of the type of `type' from the key data
518 * `key' of length of `key_len' bytes. Returns FALSE if the `key'
519 * is malformed or unsupported public key type. This function can be
520 * used to create public key from any kind of PKCS public keys that
521 * the implementation supports.
524 SilcBool silc_pkcs_public_key_alloc(SilcPKCSType type,
527 SilcPublicKey *ret_public_key);
529 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_free
533 * void silc_pkcs_public_key_free(SilcPublicKey public_key);
537 * Frees the public key.
540 void silc_pkcs_public_key_free(SilcPublicKey public_key);
542 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_export
546 * unsigned char *silc_pkcs_public_key_encode(SilcPublicKey public_key,
547 * SilcUInt32 *ret_len);
551 * Encodes the `public_key' into a binary format and returns it. Returns
552 * NULL on error. Caller must free the returned buffer.
555 unsigned char *silc_pkcs_public_key_encode(SilcPublicKey public_key,
556 SilcUInt32 *ret_len);
558 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_get_len
562 * SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
566 * Returns the key length in bits from the public key.
569 SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key);
571 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_compare
575 * SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1,
576 * SilcPublicKey key2);
580 * Compares two public keys and returns TRUE if they are same key, and
581 * FALSE if they are not same.
584 SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2);
586 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_public_key_copy
590 * SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
594 * Copies the public key indicated by `public_key' and returns new
595 * allocated public key which is indentical to the `public_key'.
598 SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key);
600 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_alloc
604 * SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
605 * unsigned char *key,
606 * SilcUInt32 key_len,
607 * SilcPrivateKey *ret_private_key);
611 * Allocates SilcPrivateKey of the type of `type' from the key data
612 * `key' of length of `key_len' bytes. Returns FALSE if the `key'
613 * is malformed or unsupported private key type.
616 SilcBool silc_pkcs_private_key_alloc(SilcPKCSType type,
619 SilcPrivateKey *ret_private_key);
621 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_get_len
625 * SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
629 * Returns the key length in bits from the private key.
632 SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key);
634 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_private_key_free
638 * void silc_pkcs_private_key_free(SilcPrivateKey private_key;
642 * Frees the private key.
645 void silc_pkcs_private_key_free(SilcPrivateKey private_key);
647 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_encrypt
651 * SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
652 * unsigned char *src, SilcUInt32 src_len,
653 * unsigned char *dst, SilcUInt32 dst_size,
654 * SilcUInt32 *dst_len);
658 * Encrypts with the public key. Returns FALSE on error.
661 SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
662 unsigned char *src, SilcUInt32 src_len,
663 unsigned char *dst, SilcUInt32 dst_size,
664 SilcUInt32 *dst_len, SilcRng rng);
666 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_decrypt
670 * SilcBool silc_pkcs_decrypt(SilcPrivateKey private_key,
671 * unsigned char *src, SilcUInt32 src_len,
672 * unsigned char *dst, SilcUInt32 dst_size,
673 * SilcUInt32 *dst_len);
677 * Decrypts with the private key. Returns FALSE on error.
680 SilcBool silc_pkcs_decrypt(SilcPrivateKey private_key,
681 unsigned char *src, SilcUInt32 src_len,
682 unsigned char *dst, SilcUInt32 dst_size,
683 SilcUInt32 *dst_len);
685 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_sign
689 * SilcBool silc_pkcs_sign(SilcPrivateKey private_key,
690 * unsigned char *src, SilcUInt32 src_len,
691 * unsigned char *dst, SilcUInt32 dst_size,
692 * SilcUInt32 *dst_len, SilcBool compute_hash,
697 * Generates signature with the private key. Returns FALSE on error.
698 * If `compute_hash' is TRUE the `hash' will be used to compute a
699 * digest over the `src'. The `hash' must always be valid.
702 SilcBool silc_pkcs_sign(SilcPrivateKey private_key,
703 unsigned char *src, SilcUInt32 src_len,
704 unsigned char *dst, SilcUInt32 dst_size,
705 SilcUInt32 *dst_len, SilcBool compute_hash,
708 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_verify
712 * SilcBool silc_pkcs_verify(SilcPublicKey public_key,
713 * unsigned char *signature,
714 * SilcUInt32 signature_len,
715 * unsigned char *data,
716 * SilcUInt32 data_len, SilcHash hash);
720 * Verifies signature. Returns FALSE on error. The 'signature' is
721 * verified against the 'data'. If the `hash' is non-NULL then the `data'
722 * will hashed before verification. If the `hash' is NULL, then the
723 * hash algorithm to be used is retrieved from the signature. If it
724 * isn't present in the signature the verification is done as is without
728 SilcBool silc_pkcs_verify(SilcPublicKey public_key,
729 unsigned char *signature,
730 SilcUInt32 signature_len,
732 SilcUInt32 data_len, SilcHash hash);
734 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_public_key
738 * SilcBool silc_pkcs_load_public_key(const char *filename,
739 * SilcPublicKey *ret_public_key);
743 * Loads public key from file and allocates new public key. Returns TRUE
744 * if loading was successful.
747 SilcBool silc_pkcs_load_public_key(const char *filename,
748 SilcPublicKey *ret_public_key);
750 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_public_key
754 * SilcBool silc_pkcs_save_public_key(const char *filename,
755 * SilcPublicKey public_key,
756 * SilcPKCSFileEncoding encoding);
760 * Saves public key into file with specified encoding. Returns FALSE
764 SilcBool silc_pkcs_save_public_key(const char *filename,
765 SilcPublicKey public_key,
766 SilcPKCSFileEncoding encoding);
768 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_private_key
772 * SilcBool silc_pkcs_load_private_key(const char *filename,
773 * const unsigned char *passphrase,
774 * SilcUInt32 passphrase_len,
775 * SilcPrivateKey *ret_private_key);
779 * Loads private key from file and allocates new private key. Returns TRUE
780 * if loading was successful. The `passphrase' is used as decryption
781 * key of the private key file, in case it is encrypted.
784 SilcBool silc_pkcs_load_private_key(const char *filename,
785 const unsigned char *passphrase,
786 SilcUInt32 passphrase_len,
787 SilcPrivateKey *ret_private_key);
789 /****f* silccrypt/SilcPKCSAPI/silc_pkcs_save_private_key
793 * SilcBool silc_pkcs_save_private_key(const char *filename,
794 * SilcPrivateKey private_key,
795 * const unsigned char *passphrase,
796 * SilcUInt32 passphrase_len,
797 * SilcPKCSFileEncoding encoding,
802 * Saves private key into file. The private key is encrypted into
803 * the file with the `passphrase' as a key, if PKCS supports encrypted
804 * private keys. Returns FALSE on error.
807 SilcBool silc_pkcs_save_private_key(const char *filename,
808 SilcPrivateKey private_key,
809 const unsigned char *passphrase,
810 SilcUInt32 passphrase_len,
811 SilcPKCSFileEncoding encoding,
814 #endif /* !SILCPKCS_H */