and silc_crypto_uninit, and silc_crypto_stack.
Changed SILC PKCS API asynchronous so that accelerators can be
used, and added SilcStack support to many routines.
Rewrote PKCS, cipher, hash and HMAC registering/unregistering.
silc_xxx_register_default does not call silc_xxx_register anymore.
User can enforece the order of algorithms by calling silc_xxx_register
in the order they want.
Changed silc_rng_get_rn_data to non-allocating.
sha256.c \
twofish.c \
blowfish.c \
+ silccrypto.c \
silccipher.c \
silchash.c \
silchmac.c \
#ifdef SILC_DIST_TOOLKIT
include_HEADERS = \
+ silccrypto.h \
silccipher.h \
silchash.h \
silchmac.h \
silcpkcs.h \
+ silcpkcs_i.h \
silcrng.h \
silcpkcs1.h \
silcpk.h
{ NULL, NULL, 0, 0, 0, 0 }
};
-/* Register a new cipher into SILC. This is used at the initialization of
- the SILC. This function allocates a new object for the cipher to be
- registered. Therefore, if memory has been allocated for the object sent
- as argument it has to be free'd after this function returns succesfully. */
+/* Register new cipher */
SilcBool silc_cipher_register(const SilcCipherObject *cipher)
{
if (silc_cipher_list) {
SilcCipherObject *entry;
silc_dlist_start(silc_cipher_list);
- while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
+ while ((entry = silc_dlist_get(silc_cipher_list))) {
if (!strcmp(entry->name, cipher->name))
return FALSE;
}
return TRUE;
}
-/* Unregister a cipher from the SILC. */
+/* Unregister a cipher */
SilcBool silc_cipher_unregister(SilcCipherObject *cipher)
{
return FALSE;
silc_dlist_start(silc_cipher_list);
- while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
+ while ((entry = silc_dlist_get(silc_cipher_list))) {
if (cipher == SILC_ALL_CIPHERS || entry == cipher) {
silc_dlist_del(silc_cipher_list, entry);
silc_free(entry->name);
return FALSE;
}
-/* Function that registers all the default ciphers (all builtin ciphers).
- The application may use this to register the default ciphers if specific
- ciphers in any specific order is not wanted. */
+/* Register default ciphers */
SilcBool silc_cipher_register_default(void)
{
-#ifndef SILC_SYMBIAN
- int i;
-
- for (i = 0; silc_default_ciphers[i].name; i++)
- silc_cipher_register(&(silc_default_ciphers[i]));
-
-#endif /* SILC_SYMBIAN */
+ /* We use builtin ciphers */
return TRUE;
}
+/* Unregister all ciphers */
+
SilcBool silc_cipher_unregister_all(void)
{
#ifndef SILC_SYMBIAN
return FALSE;
silc_dlist_start(silc_cipher_list);
- while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
+ while ((entry = silc_dlist_get(silc_cipher_list))) {
silc_cipher_unregister(entry);
if (!silc_cipher_list)
break;
SilcBool silc_cipher_alloc(const unsigned char *name, SilcCipher *new_cipher)
{
SilcCipherObject *entry = NULL;
+ int i;
SILC_LOG_DEBUG(("Allocating new cipher object"));
#ifndef SILC_SYMBIAN
+ /* First check registered list of ciphers */
if (silc_cipher_list) {
silc_dlist_start(silc_cipher_list);
- while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
+ while ((entry = silc_dlist_get(silc_cipher_list))) {
if (!strcmp(entry->name, name))
break;
}
}
-#else
- {
- /* On EPOC which don't have globals we check our constant cipher list. */
- int i;
+#endif /* SILC_SYMBIAN */
+
+ if (!entry) {
+ /* Check builtin list of ciphers */
for (i = 0; silc_default_ciphers[i].name; i++) {
if (!strcmp(silc_default_ciphers[i].name, name)) {
entry = (SilcCipherObject *)&(silc_default_ciphers[i]);
}
}
}
-#endif /* SILC_SYMBIAN */
if (entry) {
*new_cipher = silc_calloc(1, sizeof(**new_cipher));
silc_free(*new_cipher);
return FALSE;
}
+
return TRUE;
}
SilcBool silc_cipher_is_supported(const unsigned char *name)
{
-#ifndef SILC_SYMBIAN
SilcCipherObject *entry;
+ int i;
+#ifndef SILC_SYMBIAN
+ /* First check registered list of ciphers */
if (silc_cipher_list) {
silc_dlist_start(silc_cipher_list);
- while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
+ while ((entry = silc_dlist_get(silc_cipher_list))) {
if (!strcmp(entry->name, name))
return TRUE;
}
}
-#else
- {
- int i;
- for (i = 0; silc_default_ciphers[i].name; i++)
- if (!strcmp(silc_default_ciphers[i].name, name))
- return TRUE;
- }
#endif /* SILC_SYMBIAN */
+
+ /* Check builtin list of ciphers */
+ for (i = 0; silc_default_ciphers[i].name; i++)
+ if (!strcmp(silc_default_ciphers[i].name, name))
+ return TRUE;
+
return FALSE;
}
char *silc_cipher_get_supported(void)
{
- SilcCipherObject *entry;
+ SilcCipherObject *entry, *entry2;
char *list = NULL;
- int len = 0;
+ int i, len = 0;
#ifndef SILC_SYMBIAN
if (silc_cipher_list) {
silc_dlist_start(silc_cipher_list);
- while ((entry = silc_dlist_get(silc_cipher_list)) != SILC_LIST_END) {
+ while ((entry = silc_dlist_get(silc_cipher_list))) {
len += strlen(entry->name);
list = silc_realloc(list, len + 1);
len++;
}
}
-#else
- {
- int i;
- for (i = 0; silc_default_ciphers[i].name; i++) {
- entry = (SilcCipherObject *)&(silc_default_ciphers[i]);
- len += strlen(entry->name);
- list = silc_realloc(list, len + 1);
+#endif /* SILC_SYMBIAN */
- memcpy(list + (len - strlen(entry->name)),
- entry->name, strlen(entry->name));
- memcpy(list + len, ",", 1);
- len++;
+ for (i = 0; silc_default_ciphers[i].name; i++) {
+ entry = (SilcCipherObject *)&(silc_default_ciphers[i]);
+
+ if (silc_cipher_list) {
+ silc_dlist_start(silc_cipher_list);
+ while ((entry2 = silc_dlist_get(silc_cipher_list))) {
+ if (!strcmp(entry2->name, entry->name))
+ break;
+ }
+ if (entry2)
+ continue;
}
+
+ len += strlen(entry->name);
+ list = silc_realloc(list, len + 1);
+
+ memcpy(list + (len - strlen(entry->name)),
+ entry->name, strlen(entry->name));
+ memcpy(list + len, ",", 1);
+ len++;
}
-#endif /* SILC_SYMBIAN */
list[len - 1] = 0;
--- /dev/null
+/*
+
+ silccrypto.c
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 2007 Pekka Riikonen
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+*/
+
+#include "silc.h"
+
+#ifndef SILC_SYMBIAN
+SilcStack crypto_stack = NULL; /* Crypto Toolkit's global stack */
+#endif /* SILC_SYMBIAN */
+
+/* Init crypto */
+
+SilcBool silc_crypto_init(SilcStack stack)
+{
+ SILC_LOG_DEBUG(("Initializing crypto"));
+
+#ifndef SILC_SYMBIAN
+ /* Stack allocation is allowed to fail */
+ crypto_stack = silc_stack_alloc(0, stack);
+#endif /* SILC_SYMBIAN */
+
+ /* Init crypto library */
+ if (!silc_cipher_register_default()) {
+ SILC_LOG_ERROR(("Error registering ciphers"));
+ goto err;
+ }
+ if (!silc_hash_register_default()) {
+ SILC_LOG_ERROR(("Error registering hash functions"));
+ goto err;
+ }
+ if (!silc_hmac_register_default()) {
+ SILC_LOG_ERROR(("Error registering hash HMACs"));
+ goto err;
+ }
+ if (!silc_pkcs_register_default()) {
+ SILC_LOG_ERROR(("Error registering hash PKCSs"));
+ goto err;
+ }
+
+#ifdef SILC_DIST_ACC
+ /* Initialize accelerator library */
+#endif /* SILC_DIST_ACC */
+
+ return TRUE;
+
+ err:
+ silc_crypto_uninit();
+ return FALSE;
+}
+
+/* Uninit crypto */
+
+void silc_crypto_uninit(void)
+{
+ SILC_LOG_DEBUG(("Uninitializing crypto"));
+
+#ifdef SILC_DIST_ACC
+ /* Uninit accelerator library */
+#endif /* SILC_DIST_ACC */
+
+ /* Uninit crypto library */
+ silc_pkcs_unregister_all();
+ silc_hmac_unregister_all();
+ silc_hash_unregister_all();
+ silc_cipher_unregister_all();
+
+#ifndef SILC_SYMBIAN
+ silc_stack_free(crypto_stack);
+#endif /* SILC_SYMBIAN */
+}
+
+/* Return stack */
+
+SilcStack silc_crypto_stack(void)
+{
+#ifndef SILC_SYMBIAN
+ return crypto_stack;
+#else
+ return NULL;
+#endif /* SILC_SYMBIAN */
+}
--- /dev/null
+/*
+
+ silccrypto.h
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 2007 Pekka Riikonen
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+*/
+
+/****h* silccrypt/SILC Crypto Toolkit API
+ *
+ * DESCRIPTION
+ *
+ * This interface is used to initialize and uninitialize the SILC Crypto
+ * Toolkit. SILC Crypto Toolkit is initialized by calling the
+ * silc_crypto_init function. It needs to be called only once per-process
+ * but must be called before any crypto functions are used.
+ *
+ * In initialization all builtin ciphers, hash functions, HMACs, PKCSs
+ * and other algorithms will be registered to the crypto library. If user
+ * wants to register new algorithms or change the order of the automatically
+ * registered algorithms, user can do this by re-registering the algorithms
+ * in desired order.
+ *
+ * A global SilcStack, a memory pool, can be associated with the Crypto
+ * Toolkit. If it is set in initialization, all routines in the Crypto
+ * Toolkit will use that stack as its memory source. Some interfaces and
+ * libraries in the SILC Crypto Toolkit support also providing the SilcStack
+ * as an additional argument, in which case a different stack from the global
+ * one can be used.
+ *
+ ***/
+
+#ifndef SILCCRYPTO_H
+#define SILCCRYPTO_H
+
+/****f* silccrypt/SilcCryptoAPI/silc_crypto_init
+ *
+ * SYNOPSIS
+ *
+ * SilcBool silc_crypto_init(SilcStack stack);
+ *
+ * DESCRIPTION
+ *
+ * Initialize SILC Crypto Toolkit. This must be called once for every
+ * process. It initializes all libraries and registers builtin algorithms
+ * to the crypto library. If user wants to change the order of the
+ * registered algorithms, user can re-register them with their
+ * corresponding registering functions in the wanted order.
+ *
+ * If `stack' is non-NULL, it will be used by all libraries as their main
+ * source for memory. A child stack is created from the `stack'. When
+ * silc_crypto_uninit is called the allocated memory is returned back to
+ * `stack' and the caller must then free `stack'.
+ *
+ * Returns FALSE if the initialization failed. If this happens the
+ * SILC Crypto Toolkit cannot be used.
+ *
+ ***/
+SilcBool silc_crypto_init(SilcStack stack);
+
+/****f* silccrypt/SilcCryptoAPI/silc_crypto_uninit
+ *
+ * SYNOPSIS
+ *
+ * void silc_crypto_uninit(void);
+ *
+ * DESCRIPTION
+ *
+ * Uninitializes the SILC Crypto Toolkit. This should be called at the
+ * of the process before it is exited.
+ *
+ ***/
+void silc_crypto_uninit(void);
+
+/****f* silccrypt/SilcCryptoAPI/silc_crypto_stack
+ *
+ * SYNOPSIS
+ *
+ * SilcStack silc_crypto_stack(void);
+ *
+ * DESCRIPTION
+ *
+ * Returns the SILC Crypto Toolkit's global stack, the memory pool.
+ * Returns NULL if the stack does not exist.
+ *
+ * A common way to use this is to allocate a child stack from the
+ * returned stack. That operation is thread-safe, usually does not
+ * allocate any memory and is very fast. Another way to use the stack
+ * is to push it when memory is needed and then pop it when it is not
+ * needed anymore. Note however, that is not thread-safe if the stack
+ * is used in multi-threaded environment.
+ *
+ * EXAMPLE
+ *
+ * SilcStack stack;
+ *
+ * // Get child stack from global crypto stack
+ * stack = silc_stack_alloc(0, silc_crypto_stack());
+ * ...
+ *
+ * // Return memory back to the global crypto stack
+ * silc_stack_free(stack);
+ *
+ ***/
+SilcStack silc_crypto_stack(void);
+
+#endif /* SILCCRYPTO_H */
{ NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL }
};
-/* Registers a new hash function into the SILC. This function is used at
- the initialization of the SILC. */
+/* Registers a new hash function */
SilcBool silc_hash_register(const SilcHashObject *hash)
{
return TRUE;
}
-/* Unregister a hash function from the SILC. */
+/* Unregister a hash function */
SilcBool silc_hash_unregister(SilcHashObject *hash)
{
return FALSE;
}
-/* Function that registers all the default hash funcs (all builtin ones).
- The application may use this to register the default hash funcs if
- specific hash funcs in any specific order is not wanted. */
+/* Register default hash functions */
SilcBool silc_hash_register_default(void)
{
-#ifndef SILC_SYMBIAN
- int i;
-
- for (i = 0; silc_default_hash[i].name; i++)
- silc_hash_register(&(silc_default_hash[i]));
-
-#endif /* SILC_SYMBIAN */
+ /* We use builtin hash functions */
return TRUE;
}
+/* Unregister all hash functions */
+
SilcBool silc_hash_unregister_all(void)
{
#ifndef SILC_SYMBIAN
SilcBool silc_hash_alloc(const unsigned char *name, SilcHash *new_hash)
{
SilcHashObject *entry = NULL;
+ int i;
SILC_LOG_DEBUG(("Allocating new hash %s", name));
#ifndef SILC_SYMBIAN
+ /* Check list of registered hash functions */
if (silc_hash_list) {
silc_dlist_start(silc_hash_list);
while ((entry = silc_dlist_get(silc_hash_list)) != SILC_LIST_END) {
break;
}
}
-#else
- {
- /* On EPOC which don't have globals we check our constant hash list. */
- int i;
+#endif /* SILC_SYMBIAN */
+
+ if (!entry) {
+ /* Check builtin hash function list */
for (i = 0; silc_default_hash[i].name; i++) {
if (!strcmp(silc_default_hash[i].name, name)) {
entry = (SilcHashObject *)&(silc_default_hash[i]);
}
}
}
-#endif /* SILC_SYMBIAN */
if (entry) {
*new_hash = silc_calloc(1, sizeof(**new_hash));
SilcBool silc_hash_alloc_by_oid(const char *oid, SilcHash *new_hash)
{
SilcHashObject *entry = NULL;
+ int i;
SILC_LOG_DEBUG(("Allocating new hash %s", oid));
#ifndef SILC_SYMBIAN
+ /* Check list of registered hash functions */
if (silc_hash_list) {
silc_dlist_start(silc_hash_list);
while ((entry = silc_dlist_get(silc_hash_list)) != SILC_LIST_END) {
break;
}
}
-#else
- {
- /* On EPOC which don't have globals we check our constant hash list. */
- int i;
+#endif /* SILC_SYMBIAN */
+
+ if (!entry) {
+ /* Check builtin hash function list */
for (i = 0; silc_default_hash[i].oid; i++) {
if (!strcmp(silc_default_hash[i].oid, oid)) {
entry = (SilcHashObject *)&(silc_default_hash[i]);
}
}
}
-#endif /* SILC_SYMBIAN */
if (entry) {
*new_hash = silc_calloc(1, sizeof(**new_hash));
SilcBool silc_hash_is_supported(const unsigned char *name)
{
-#ifndef SILC_SYMBIAN
SilcHashObject *entry;
+ int i;
+#ifndef SILC_SYMBIAN
if (silc_hash_list) {
silc_dlist_start(silc_hash_list);
while ((entry = silc_dlist_get(silc_hash_list)) != SILC_LIST_END) {
return TRUE;
}
}
-#else
- {
- int i;
- for (i = 0; silc_default_hash[i].name; i++)
- if (!strcmp(silc_default_hash[i].name, name))
- return TRUE;
- }
#endif /* SILC_SYMBIAN */
+
+ for (i = 0; silc_default_hash[i].name; i++)
+ if (!strcmp(silc_default_hash[i].name, name))
+ return TRUE;
+
return FALSE;
}
char *silc_hash_get_supported(void)
{
- SilcHashObject *entry;
+ SilcHashObject *entry, *entry2;
char *list = NULL;
- int len = 0;
+ int i, len = 0;
#ifndef SILC_SYMBIAN
if (silc_hash_list) {
len++;
}
}
-#else
- {
- int i;
- for (i = 0; silc_default_hash[i].name; i++) {
- entry = (SilcHashObject *)&(silc_default_hash[i]);
- len += strlen(entry->name);
- list = silc_realloc(list, len + 1);
+#endif /* SILC_SYMBIAN */
- memcpy(list + (len - strlen(entry->name)),
- entry->name, strlen(entry->name));
- memcpy(list + len, ",", 1);
- len++;
+ for (i = 0; silc_default_hash[i].name; i++) {
+ entry = (SilcHashObject *)&(silc_default_hash[i]);
+
+ if (silc_hash_list) {
+ silc_dlist_start(silc_hash_list);
+ while ((entry2 = silc_dlist_get(silc_hash_list)) != SILC_LIST_END) {
+ if (!strcmp(entry2->name, entry->name))
+ break;
+ }
+ if (entry2)
+ continue;
}
+
+ len += strlen(entry->name);
+ list = silc_realloc(list, len + 1);
+
+ memcpy(list + (len - strlen(entry->name)),
+ entry->name, strlen(entry->name));
+ memcpy(list + len, ",", 1);
+ len++;
}
-#endif /* SILC_SYMBIAN */
list[len - 1] = 0;
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1999 - 2006 Pekka Riikonen
+ Copyright (C) 1999 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
}
}
-/* Registers a new HMAC into the SILC. This function is used at the
- initialization of the SILC. */
+/* Registers a new HMAC */
SilcBool silc_hmac_register(const SilcHmacObject *hmac)
{
return TRUE;
}
-/* Unregister a HMAC from the SILC. */
+/* Unregister a HMAC */
SilcBool silc_hmac_unregister(SilcHmacObject *hmac)
{
return FALSE;
}
-/* Function that registers all the default hmacs (all builtin ones).
- The application may use this to register the default hmacs if
- specific hmacs in any specific order is not wanted. */
+/* Register default HMACs */
SilcBool silc_hmac_register_default(void)
{
-#ifndef SILC_SYMBIAN
- int i;
-
- for (i = 0; silc_default_hmacs[i].name; i++)
- silc_hmac_register(&(silc_default_hmacs[i]));
-
-#endif /* SILC_SYMBIAN */
+ /* We use builtin HMACs */
return TRUE;
}
+/* Unregister all HMACs */
+
SilcBool silc_hmac_unregister_all(void)
{
#ifndef SILC_SYMBIAN
SilcBool silc_hmac_alloc(const char *name, SilcHash hash, SilcHmac *new_hmac)
{
+ SilcHmacObject *entry = NULL;
+ int i;
+
SILC_LOG_DEBUG(("Allocating new HMAC"));
/* Allocate the new object */
(*new_hmac)->hash = hash;
#ifndef SILC_SYMBIAN
+ /* Check registered list of HMACs */
if (silc_hmac_list) {
- SilcHmacObject *entry;
silc_dlist_start(silc_hmac_list);
while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
if (!strcmp(entry->name, name)) {
}
}
}
-#else
- {
- /* On EPOC which don't have globals we check our constant hash list. */
- int i;
+#endif /* SILC_SYMBIAN */
+
+ if (!entry) {
+ /* Check builtin list of HMACs */
for (i = 0; silc_default_hmacs[i].name; i++) {
if (!strcmp(silc_default_hmacs[i].name, name)) {
(*new_hmac)->hmac = (SilcHmacObject *)&(silc_default_hmacs[i]);
}
}
}
-#endif /* SILC_SYMBIAN */
silc_free(*new_hmac);
*new_hmac = NULL;
SilcBool silc_hmac_is_supported(const char *name)
{
-#ifndef SILC_SYMBIAN
SilcHmacObject *entry;
+ int i;
if (!name)
return FALSE;
+#ifndef SILC_SYMBIAN
if (silc_hmac_list) {
silc_dlist_start(silc_hmac_list);
while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
return TRUE;
}
}
-#else
- {
- int i;
- for (i = 0; silc_default_hmacs[i].name; i++)
- if (!strcmp(silc_default_hmacs[i].name, name))
- return TRUE;
- }
#endif /* SILC_SYMBIAN */
+
+ for (i = 0; silc_default_hmacs[i].name; i++)
+ if (!strcmp(silc_default_hmacs[i].name, name))
+ return TRUE;
+
return FALSE;
}
char *silc_hmac_get_supported()
{
- SilcHmacObject *entry;
+ SilcHmacObject *entry, *entry2;
char *list = NULL;
- int len = 0;
+ int len = 0, i;
#ifndef SILC_SYMBIAN
if (silc_hmac_list) {
len++;
}
}
-#else
- {
- int i;
- for (i = 0; silc_default_hmacs[i].name; i++) {
- entry = (SilcHmacObject *)&(silc_default_hmacs[i]);
- len += strlen(entry->name);
- list = silc_realloc(list, len + 1);
+#endif /* SILC_SYMBIAN */
- memcpy(list + (len - strlen(entry->name)),
- entry->name, strlen(entry->name));
- memcpy(list + len, ",", 1);
- len++;
+
+ for (i = 0; silc_default_hmacs[i].name; i++) {
+ entry = (SilcHmacObject *)&(silc_default_hmacs[i]);
+
+ if (silc_hmac_list) {
+ silc_dlist_start(silc_hmac_list);
+ while ((entry2 = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
+ if (!strcmp(entry2->name, entry->name))
+ break;
+ }
+ if (entry2)
+ continue;
}
+
+ len += strlen(entry->name);
+ list = silc_realloc(list, len + 1);
+
+ memcpy(list + (len - strlen(entry->name)),
+ entry->name, strlen(entry->name));
+ memcpy(list + len, ",", 1);
+ len++;
}
-#endif /* SILC_SYMBIAN */
list[len - 1] = 0;
(*ret_private_key)->private_key = privkey;
/* Generate the algorithm key pair */
- if (!alg->generate_key(bits_key_len, rng, &pubkey->public_key,
+ if (!alg->generate_key(alg, bits_key_len, rng, &pubkey->public_key,
&privkey->private_key)) {
silc_free(pubkey);
silc_free(privkey);
arguments is NULL those are not encoded into the identifier string.
Protocol says that at least username and host must be provided. */
-char *silc_pkcs_silc_encode_identifier(char *username, char *host,
+char *silc_pkcs_silc_encode_identifier(SilcStack stack,
+ char *username, char *host,
char *realname, char *email,
char *org, char *country,
char *version)
memset(&buf, 0, sizeof(buf));
if (username)
- silc_buffer_format(&buf,
- SILC_STR_ADVANCE,
- SILC_STR_UI32_STRING("UN="),
- SILC_STR_UI32_STRING(username),
- SILC_STR_END);
+ silc_buffer_sformat(stack, &buf,
+ SILC_STR_ADVANCE,
+ SILC_STR_UI32_STRING("UN="),
+ SILC_STR_UI32_STRING(username),
+ SILC_STR_END);
if (host)
- silc_buffer_format(&buf,
- SILC_STR_ADVANCE,
- SILC_STR_UI32_STRING(", "),
- SILC_STR_UI32_STRING("HN="),
- SILC_STR_UI32_STRING(host),
- SILC_STR_END);
+ silc_buffer_sformat(stack, &buf,
+ SILC_STR_ADVANCE,
+ SILC_STR_UI32_STRING(", "),
+ SILC_STR_UI32_STRING("HN="),
+ SILC_STR_UI32_STRING(host),
+ SILC_STR_END);
if (realname)
- silc_buffer_format(&buf,
- SILC_STR_ADVANCE,
- SILC_STR_UI32_STRING(", "),
- SILC_STR_UI32_STRING("RN="),
- SILC_STR_UI32_STRING(realname),
- SILC_STR_END);
+ silc_buffer_sformat(stack, &buf,
+ SILC_STR_ADVANCE,
+ SILC_STR_UI32_STRING(", "),
+ SILC_STR_UI32_STRING("RN="),
+ SILC_STR_UI32_STRING(realname),
+ SILC_STR_END);
if (email)
- silc_buffer_format(&buf,
- SILC_STR_ADVANCE,
- SILC_STR_UI32_STRING(", "),
- SILC_STR_UI32_STRING("E="),
- SILC_STR_UI32_STRING(email),
- SILC_STR_END);
+ silc_buffer_sformat(stack, &buf,
+ SILC_STR_ADVANCE,
+ SILC_STR_UI32_STRING(", "),
+ SILC_STR_UI32_STRING("E="),
+ SILC_STR_UI32_STRING(email),
+ SILC_STR_END);
if (org)
- silc_buffer_format(&buf,
- SILC_STR_ADVANCE,
- SILC_STR_UI32_STRING(", "),
- SILC_STR_UI32_STRING("O="),
- SILC_STR_UI32_STRING(org),
- SILC_STR_END);
+ silc_buffer_sformat(stack, &buf,
+ SILC_STR_ADVANCE,
+ SILC_STR_UI32_STRING(", "),
+ SILC_STR_UI32_STRING("O="),
+ SILC_STR_UI32_STRING(org),
+ SILC_STR_END);
if (country)
- silc_buffer_format(&buf,
- SILC_STR_ADVANCE,
- SILC_STR_UI32_STRING(", "),
- SILC_STR_UI32_STRING("C="),
- SILC_STR_UI32_STRING(country),
- SILC_STR_END);
+ silc_buffer_sformat(stack, &buf,
+ SILC_STR_ADVANCE,
+ SILC_STR_UI32_STRING(", "),
+ SILC_STR_UI32_STRING("C="),
+ SILC_STR_UI32_STRING(country),
+ SILC_STR_END);
if (version) {
if (strlen(version) > 1 || !isdigit(version[0])) {
- silc_buffer_purge(&buf);
+ silc_buffer_spurge(stack, &buf);
return NULL;
}
- silc_buffer_format(&buf,
- SILC_STR_ADVANCE,
- SILC_STR_UI32_STRING(", "),
- SILC_STR_UI32_STRING("V="),
- SILC_STR_UI32_STRING(version),
- SILC_STR_END);
+ silc_buffer_sformat(stack, &buf,
+ SILC_STR_ADVANCE,
+ SILC_STR_UI32_STRING(", "),
+ SILC_STR_UI32_STRING("V="),
+ SILC_STR_UI32_STRING(version),
+ SILC_STR_END);
}
- silc_buffer_format(&buf, SILC_STR_UI_CHAR(0), SILC_STR_END);
+ silc_buffer_sformat(stack, &buf, SILC_STR_UI_CHAR(0), SILC_STR_END);
identifier = silc_buffer_steal(&buf, NULL);
return identifier;
/* Returns PKCS algorithm context */
-const SilcPKCSAlgorithm *silc_pkcs_silc_get_algorithm(void *public_key)
+const SilcPKCSAlgorithm *
+silc_pkcs_silc_get_algorithm(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key)
{
SilcSILCPublicKey silc_pubkey = public_key;
return silc_pubkey->pkcs;
/* Imports SILC protocol style public key from SILC public key file */
-SilcBool silc_pkcs_silc_import_public_key_file(unsigned char *filedata,
- SilcUInt32 filedata_len,
- SilcPKCSFileEncoding encoding,
- void **ret_public_key)
+SilcBool
+silc_pkcs_silc_import_public_key_file(const struct SilcPKCSObjectStruct *pkcs,
+ unsigned char *filedata,
+ SilcUInt32 filedata_len,
+ SilcPKCSFileEncoding encoding,
+ void **ret_public_key)
{
SilcUInt32 i, len;
unsigned char *data = NULL;
break;
case SILC_PKCS_FILE_BASE64:
- data = silc_base64_decode(filedata, filedata_len, &filedata_len);
+ data = silc_base64_decode(NULL, filedata, filedata_len, &filedata_len);
if (!data)
return FALSE;
filedata = data;
break;
}
- ret = silc_pkcs_silc_import_public_key(filedata, filedata_len,
+ ret = silc_pkcs_silc_import_public_key(pkcs, filedata, filedata_len,
ret_public_key);
silc_free(data);
/* Imports SILC protocol style public key */
-int silc_pkcs_silc_import_public_key(unsigned char *key,
+int silc_pkcs_silc_import_public_key(const struct SilcPKCSObjectStruct *pkcs,
+ void *key,
SilcUInt32 key_len,
void **ret_public_key)
{
- const SilcPKCSAlgorithm *pkcs;
+ const SilcPKCSAlgorithm *alg;
SilcBufferStruct buf, alg_key;
SilcSILCPublicKey silc_pubkey = NULL;
SilcAsn1 asn1 = NULL;
if (!silc_pubkey->identifier.version ||
atoi(silc_pubkey->identifier.version) <= 1) {
/* Version 1 */
- pkcs = silc_pkcs_find_algorithm(pkcs_name, "pkcs1-no-oid");
+ alg = silc_pkcs_find_algorithm(pkcs_name, "pkcs1-no-oid");
} else {
/* Version 2 and newer */
- pkcs = silc_pkcs_find_algorithm(pkcs_name, "pkcs1");
+ alg = silc_pkcs_find_algorithm(pkcs_name, "pkcs1");
}
- if (!pkcs) {
+ if (!alg) {
SILC_LOG_DEBUG(("Unsupported PKCS algorithm: rsa"));
goto err;
}
- silc_pubkey->pkcs = pkcs;
+ silc_pubkey->pkcs = alg;
if (keydata_len < 4)
goto err;
}
/* Import PKCS algorithm public key */
- if (!pkcs->import_public_key(alg_key.data, silc_buffer_len(&alg_key),
- &silc_pubkey->public_key))
+ if (!alg->import_public_key(alg, alg_key.data, silc_buffer_len(&alg_key),
+ &silc_pubkey->public_key))
goto err;
silc_free(pkcs_name);
/* Exports public key as SILC protocol style public key file */
unsigned char *
-silc_pkcs_silc_export_public_key_file(void *public_key,
+silc_pkcs_silc_export_public_key_file(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ void *public_key,
SilcPKCSFileEncoding encoding,
SilcUInt32 *ret_len)
{
SILC_LOG_DEBUG(("Encoding SILC public key file"));
/* Export key */
- key = silc_pkcs_silc_export_public_key(public_key, &key_len);
+ key = silc_pkcs_silc_export_public_key(pkcs, stack, public_key, &key_len);
if (!key)
return NULL;
break;
case SILC_PKCS_FILE_BASE64:
- data = silc_base64_encode_file(key, key_len);
+ data = silc_base64_encode_file(stack, key, key_len);
if (!data)
return NULL;
- silc_free(key);
+ silc_sfree(stack, key);
key = data;
key_len = strlen(data);
break;
}
/* Encode SILC public key file */
- buf = silc_buffer_alloc_size(key_len +
- (strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN) +
- strlen(SILC_PKCS_PUBLIC_KEYFILE_END)));
+ buf = silc_buffer_salloc_size(stack, key_len +
+ (strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN) +
+ strlen(SILC_PKCS_PUBLIC_KEYFILE_END)));
if (!buf) {
- silc_free(key);
+ silc_sfree(stack, key);
return NULL;
}
- if (silc_buffer_format(buf,
- SILC_STR_UI32_STRING(SILC_PKCS_PUBLIC_KEYFILE_BEGIN),
- SILC_STR_UI_XNSTRING(key, key_len),
- SILC_STR_UI32_STRING(SILC_PKCS_PUBLIC_KEYFILE_END),
- SILC_STR_END) < 0) {
- silc_buffer_free(buf);
- silc_free(key);
+ if (silc_buffer_sformat(stack, buf,
+ SILC_STR_UI32_STRING(SILC_PKCS_PUBLIC_KEYFILE_BEGIN),
+ SILC_STR_UI_XNSTRING(key, key_len),
+ SILC_STR_UI32_STRING(SILC_PKCS_PUBLIC_KEYFILE_END),
+ SILC_STR_END) < 0) {
+ silc_buffer_sfree(stack, buf);
+ silc_sfree(stack, key);
return NULL;
}
- silc_free(key);
+ silc_sfree(stack, key);
key = silc_buffer_steal(buf, ret_len);
- silc_buffer_free(buf);
+ silc_buffer_sfree(stack, buf);
return key;
}
/* Exports public key as SILC protocol style public key */
-unsigned char *silc_pkcs_silc_export_public_key(void *public_key,
- SilcUInt32 *ret_len)
+unsigned char *
+silc_pkcs_silc_export_public_key(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ void *public_key,
+ SilcUInt32 *ret_len)
{
SilcSILCPublicKey silc_pubkey = public_key;
- const SilcPKCSAlgorithm *pkcs = silc_pubkey->pkcs;
+ const SilcPKCSAlgorithm *alg = silc_pubkey->pkcs;
SilcBufferStruct alg_key;
SilcBuffer buf = NULL;
SilcAsn1 asn1 = NULL;
SILC_LOG_DEBUG(("Encoding SILC public key"));
/* Export PKCS algorithm public key */
- if (pkcs->export_public_key)
- pk = pkcs->export_public_key(silc_pubkey->public_key, &pk_len);
+ if (alg->export_public_key)
+ pk = alg->export_public_key(alg, stack, silc_pubkey->public_key, &pk_len);
if (!pk) {
SILC_LOG_ERROR(("Error exporting PKCS algorithm key"));
return NULL;
/* Encode identifier */
identifier =
- silc_pkcs_silc_encode_identifier(silc_pubkey->identifier.username,
+ silc_pkcs_silc_encode_identifier(stack,
+ silc_pubkey->identifier.username,
silc_pubkey->identifier.host,
silc_pubkey->identifier.realname,
silc_pubkey->identifier.email,
goto err;
}
- asn1 = silc_asn1_alloc(NULL);
+ asn1 = silc_asn1_alloc(stack);
if (!asn1)
goto err;
- if (!strcmp(pkcs->name, "rsa")) {
+ if (!strcmp(alg->name, "rsa")) {
/* Parse the PKCS #1 public key */
SilcMPInt n, e;
SilcUInt32 n_len, e_len;
if (!nb)
goto err;
key_len = e_len + 4 + n_len + 4;
- key = silc_calloc(key_len, sizeof(*key));
+ key = silc_scalloc(stack, key_len, sizeof(*key));
if (!key)
goto err;
silc_free(nb);
silc_free(eb);
- } else if (!strcmp(pkcs->name, "dsa")) {
+ } else if (!strcmp(alg->name, "dsa")) {
SILC_NOT_IMPLEMENTED("SILC DSA Public Key");
goto err;
} else {
- SILC_LOG_ERROR(("Unsupported PKCS algorithm: %s", pkcs->name));
+ SILC_LOG_ERROR(("Unsupported PKCS algorithm: %s", alg->name));
goto err;
}
/* Encode SILC Public Key */
- totlen = 2 + strlen(pkcs->name) + 2 + strlen(identifier) + key_len;
- buf = silc_buffer_alloc_size(totlen + 4);
+ totlen = 2 + strlen(alg->name) + 2 + strlen(identifier) + key_len;
+ buf = silc_buffer_salloc_size(stack, totlen + 4);
if (!buf)
goto err;
- if (silc_buffer_format(buf,
- SILC_STR_UI_INT(totlen),
- SILC_STR_UI_SHORT(strlen(pkcs->name)),
- SILC_STR_UI32_STRING(pkcs->name),
- SILC_STR_UI_SHORT(strlen(identifier)),
- SILC_STR_UI32_STRING(identifier),
- SILC_STR_UI_XNSTRING(key, key_len),
- SILC_STR_END) < 0)
+ if (silc_buffer_sformat(stack, buf,
+ SILC_STR_UI_INT(totlen),
+ SILC_STR_UI_SHORT(strlen(alg->name)),
+ SILC_STR_UI32_STRING(alg->name),
+ SILC_STR_UI_SHORT(strlen(identifier)),
+ SILC_STR_UI32_STRING(identifier),
+ SILC_STR_UI_XNSTRING(key, key_len),
+ SILC_STR_END) < 0)
goto err;
ret = silc_buffer_steal(buf, ret_len);
- silc_buffer_free(buf);
- silc_free(key);
- silc_free(identifier);
- silc_buffer_purge(&alg_key);
+ silc_buffer_sfree(stack, buf);
+ silc_sfree(stack, key);
+ silc_sfree(stack, identifier);
+ silc_buffer_spurge(stack, &alg_key);
silc_asn1_free(asn1);
return ret;
err:
- silc_free(identifier);
- silc_free(pk);
- silc_free(key);
- if (buf)
- silc_buffer_free(buf);
+ silc_sfree(stack, identifier);
+ silc_sfree(stack, pk);
+ silc_sfree(stack, key);
+ silc_buffer_sfree(stack, buf);
if (asn1)
silc_asn1_free(asn1);
return NULL;
/* Return key length */
-SilcUInt32 silc_pkcs_silc_public_key_bitlen(void *public_key)
+SilcUInt32
+silc_pkcs_silc_public_key_bitlen(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key)
{
SilcSILCPublicKey silc_pubkey = public_key;
- return silc_pubkey->pkcs->public_key_bitlen(silc_pubkey->public_key);
+ return silc_pubkey->pkcs->public_key_bitlen(silc_pubkey->pkcs,
+ silc_pubkey->public_key);
}
/* Copy public key */
-void *silc_pkcs_silc_public_key_copy(void *public_key)
+void *silc_pkcs_silc_public_key_copy(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key)
{
SilcSILCPublicKey silc_pubkey = public_key, new_pubkey;
SilcPublicKeyIdentifier ident = &silc_pubkey->identifier;
new_pubkey->pkcs = silc_pubkey->pkcs;
new_pubkey->public_key =
- silc_pubkey->pkcs->public_key_copy(silc_pubkey->public_key);
+ silc_pubkey->pkcs->public_key_copy(silc_pubkey->pkcs,
+ silc_pubkey->public_key);
if (!new_pubkey->public_key) {
silc_free(new_pubkey);
return NULL;
/* Compares public keys */
-SilcBool silc_pkcs_silc_public_key_compare(void *key1, void *key2)
+SilcBool
+silc_pkcs_silc_public_key_compare(const struct SilcPKCSObjectStruct *pkcs,
+ void *key1, void *key2)
{
SilcSILCPublicKey k1 = key1, k2 = key2;
strcmp(k1->identifier.version, k2->identifier.version)))
return FALSE;
- return k1->pkcs->public_key_compare(k1->public_key, k2->public_key);
+ return k1->pkcs->public_key_compare(k1->pkcs, k1->public_key, k2->public_key);
}
/* Frees public key */
-void silc_pkcs_silc_public_key_free(void *public_key)
+void silc_pkcs_silc_public_key_free(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key)
{
SilcSILCPublicKey silc_pubkey = public_key;
- silc_pubkey->pkcs->public_key_free(silc_pubkey->public_key);
+ silc_pubkey->pkcs->public_key_free(silc_pubkey->pkcs,
+ silc_pubkey->public_key);
silc_free(silc_pubkey->identifier.username);
silc_free(silc_pubkey->identifier.host);
/* Imports SILC implementation style private key file */
-SilcBool silc_pkcs_silc_import_private_key_file(unsigned char *filedata,
- SilcUInt32 filedata_len,
- const char *passphrase,
- SilcUInt32 passphrase_len,
- SilcPKCSFileEncoding encoding,
- void **ret_private_key)
+SilcBool
+silc_pkcs_silc_import_private_key_file(const struct SilcPKCSObjectStruct *pkcs,
+ unsigned char *filedata,
+ SilcUInt32 filedata_len,
+ const char *passphrase,
+ SilcUInt32 passphrase_len,
+ SilcPKCSFileEncoding encoding,
+ void **ret_private_key)
{
SilcCipher aes;
SilcHash sha1;
break;
case SILC_PKCS_FILE_BASE64:
- data = silc_base64_decode(filedata, filedata_len, &len);
+ data = silc_base64_decode(NULL, filedata, filedata_len, &len);
if (!data)
return FALSE;
filedata = data;
silc_cipher_free(aes);
/* Import the private key */
- ret = silc_pkcs_silc_import_private_key(filedata, len, ret_private_key);
+ ret = silc_pkcs_silc_import_private_key(pkcs, filedata, len, ret_private_key);
silc_free(data);
/* Imports SILC implementation style private key */
-int silc_pkcs_silc_import_private_key(unsigned char *key,
+int silc_pkcs_silc_import_private_key(const struct SilcPKCSObjectStruct *pkcs,
+ void *key,
SilcUInt32 key_len,
void **ret_private_key)
{
SilcBufferStruct buf;
- const SilcPKCSAlgorithm *pkcs;
+ const SilcPKCSAlgorithm *alg;
SilcBufferStruct alg_key;
SilcSILCPrivateKey silc_privkey = NULL;
SilcAsn1 asn1 = NULL;
if (!ret_private_key)
return 0;
- silc_buffer_set(&buf, key, key_len);
+ silc_buffer_set(&buf, (unsigned char *)key, key_len);
/* Get algorithm name and identifier */
ret =
versions. */
if (ver == 0 || ver == SILC_PRIVATE_KEY_VERSION_1) {
/* Version 0 and 1 */
- pkcs = silc_pkcs_find_algorithm(pkcs_name, "pkcs1-no-oid");
+ alg = silc_pkcs_find_algorithm(pkcs_name, "pkcs1-no-oid");
} else {
/* Version 2 and newer */
- pkcs = silc_pkcs_find_algorithm(pkcs_name, "pkcs1");
+ alg = silc_pkcs_find_algorithm(pkcs_name, "pkcs1");
}
- if (!pkcs) {
+ if (!alg) {
SILC_LOG_DEBUG(("Unsupported PKCS algorithm"));
goto err;
}
- silc_privkey->pkcs = pkcs;
+ silc_privkey->pkcs = alg;
SILC_LOG_DEBUG(("Private key version %s",
(ver == SILC_PRIVATE_KEY_VERSION_1 ? "1" :
}
/* Import PKCS algorithm private key */
- if (!pkcs->import_private_key(alg_key.data, silc_buffer_len(&alg_key),
- &silc_privkey->private_key))
+ if (!alg->import_private_key(alg, alg_key.data, silc_buffer_len(&alg_key),
+ &silc_privkey->private_key))
goto err;
silc_free(pkcs_name);
/* Exports private key as SILC implementation style private key file */
unsigned char *
-silc_pkcs_silc_export_private_key_file(void *private_key,
+silc_pkcs_silc_export_private_key_file(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ void *private_key,
const char *passphrase,
SilcUInt32 passphrase_len,
SilcPKCSFileEncoding encoding,
SILC_LOG_DEBUG(("Encoding SILC private key file"));
/* Export the private key */
- key = silc_pkcs_silc_export_private_key(private_key, &key_len);
+ key = silc_pkcs_silc_export_private_key(pkcs, stack, private_key, &key_len);
if (!key)
return NULL;
/* Allocate the AES cipher */
if (!silc_cipher_alloc("aes-256-cbc", &aes)) {
SILC_LOG_ERROR(("Could not allocate AES cipher, probably not registered"));
- silc_free(key);
+ silc_sfree(stack, key);
return NULL;
}
blocklen = silc_cipher_get_block_len(aes);
if (blocklen * 2 > sizeof(tmp)) {
silc_cipher_free(aes);
- silc_free(key);
+ silc_sfree(stack, key);
return NULL;
}
/* Allocate SHA1 hash */
if (!silc_hash_alloc("sha1", &sha1)) {
SILC_LOG_ERROR(("Could not allocate SHA1 hash, probably not registered"));
+ silc_sfree(stack, key);
silc_cipher_free(aes);
return NULL;
}
/* Allocate HMAC */
if (!silc_hmac_alloc("hmac-sha1-96", NULL, &sha1hmac)) {
SILC_LOG_ERROR(("Could not allocate SHA1 HMAC, probably not registered"));
+ silc_sfree(stack, key);
silc_hash_free(sha1);
silc_cipher_free(aes);
return NULL;
/* Allocate buffer for encryption */
len = silc_hmac_len(sha1hmac);
padlen = 16 + (16 - ((key_len + 4) % blocklen));
- enc = silc_buffer_alloc_size(4 + 4 + key_len + padlen + len);
+ enc = silc_buffer_salloc_size(stack, 4 + 4 + key_len + padlen + len);
if (!enc) {
+ silc_sfree(stack, key);
silc_hmac_free(sha1hmac);
silc_hash_free(sha1);
silc_cipher_free(aes);
silc_buffer_pull(enc, 4);
/* Encode the buffer */
- silc_buffer_format(enc,
- SILC_STR_UI_INT(key_len),
- SILC_STR_UI_XNSTRING(key, key_len),
- SILC_STR_UI_XNSTRING(tmp, padlen),
- SILC_STR_END);
- silc_free(key);
+ silc_buffer_sformat(stack, enc,
+ SILC_STR_UI_INT(key_len),
+ SILC_STR_UI_XNSTRING(key, key_len),
+ SILC_STR_UI_XNSTRING(tmp, padlen),
+ SILC_STR_END);
+ silc_sfree(stack, key);
/* Encrypt. */
silc_cipher_encrypt(aes, enc->data, enc->data, silc_buffer_len(enc) - len,
break;
case SILC_PKCS_FILE_BASE64:
- data = silc_base64_encode_file(enc->data, silc_buffer_len(enc));
+ data = silc_base64_encode_file(stack, enc->data, silc_buffer_len(enc));
if (!data) {
silc_buffer_clear(enc);
- silc_buffer_free(enc);
+ silc_buffer_sfree(stack, enc);
return NULL;
}
- silc_free(silc_buffer_steal(enc, NULL));
+ silc_sfree(stack, silc_buffer_steal(enc, NULL));
silc_buffer_set(enc, data, strlen(data));
break;
}
/* Encode the data and save to file */
len = key_len + (strlen(SILC_PKCS_PRIVATE_KEYFILE_BEGIN) +
strlen(SILC_PKCS_PRIVATE_KEYFILE_END));
- buf = silc_buffer_alloc_size(len);
+ buf = silc_buffer_salloc_size(stack, len);
if (!buf) {
- silc_buffer_free(enc);
+ silc_buffer_sfree(stack, enc);
return NULL;
}
- silc_buffer_format(buf,
- SILC_STR_UI32_STRING(SILC_PKCS_PRIVATE_KEYFILE_BEGIN),
- SILC_STR_UI_XNSTRING(key, key_len),
- SILC_STR_UI32_STRING(SILC_PKCS_PRIVATE_KEYFILE_END),
- SILC_STR_END);
+ silc_buffer_sformat(stack, buf,
+ SILC_STR_UI32_STRING(SILC_PKCS_PRIVATE_KEYFILE_BEGIN),
+ SILC_STR_UI_XNSTRING(key, key_len),
+ SILC_STR_UI32_STRING(SILC_PKCS_PRIVATE_KEYFILE_END),
+ SILC_STR_END);
- silc_buffer_free(enc);
+ silc_buffer_sfree(stack, enc);
data = silc_buffer_steal(buf, ret_len);
- silc_buffer_free(buf);
+ silc_buffer_sfree(stack, buf);
return data;
}
/* Exports private key as SILC implementation style private key */
-unsigned char *silc_pkcs_silc_export_private_key(void *private_key,
- SilcUInt32 *ret_len)
+unsigned char *
+silc_pkcs_silc_export_private_key(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ void *private_key,
+ SilcUInt32 *ret_len)
{
SilcSILCPrivateKey silc_privkey = private_key;
- const SilcPKCSAlgorithm *pkcs = silc_privkey->pkcs;
+ const SilcPKCSAlgorithm *alg = silc_privkey->pkcs;
SilcBufferStruct alg_key;
SilcBuffer buf = NULL;
SilcAsn1 asn1 = NULL;
SILC_LOG_DEBUG(("Encoding SILC private key"));
/* Export PKCS algorithm private key */
- if (pkcs->export_private_key)
- prv = pkcs->export_private_key(silc_privkey->private_key, &prv_len);
+ if (alg->export_private_key)
+ prv = alg->export_private_key(alg, stack,
+ silc_privkey->private_key, &prv_len);
if (!prv)
return NULL;
silc_buffer_set(&alg_key, prv, prv_len);
- asn1 = silc_asn1_alloc(NULL);
+ asn1 = silc_asn1_alloc(stack);
if (!asn1)
goto err;
- if (!strcmp(pkcs->name, "rsa")) {
+ if (!strcmp(alg->name, "rsa")) {
/* Parse the PKCS #1 private key */
SilcMPInt n, e, d, dp, dq, qp, p, q;
SilcUInt32 e_len, n_len, d_len, dp_len, dq_len,
len = 4 + e_len + 4 + n_len + 4 + d_len + 4+ dp_len + 4 +
dq_len + 4 + qp_len + 4 + p_len + 4 + q_len + 4;
- buf = silc_buffer_alloc_size(len);
+ buf = silc_buffer_salloc_size(stack, len);
if (!buf)
goto err;
- if (silc_buffer_format(buf,
- SILC_STR_UI_INT(SILC_PRIVATE_KEY_VERSION_1),
- SILC_STR_UI_INT(e_len),
- SILC_STR_UI_XNSTRING(eb, e_len),
- SILC_STR_UI_INT(n_len),
- SILC_STR_UI_XNSTRING(nb, n_len),
- SILC_STR_UI_INT(d_len),
- SILC_STR_UI_XNSTRING(db, d_len),
- SILC_STR_UI_INT(dp_len),
- SILC_STR_UI_XNSTRING(dpb, dp_len),
- SILC_STR_UI_INT(dq_len),
- SILC_STR_UI_XNSTRING(dqb, dq_len),
- SILC_STR_UI_INT(qp_len),
- SILC_STR_UI_XNSTRING(qpb, qp_len),
- SILC_STR_UI_INT(p_len),
- SILC_STR_UI_XNSTRING(pb, p_len),
- SILC_STR_UI_INT(q_len),
- SILC_STR_UI_XNSTRING(qb, q_len),
- SILC_STR_END) < 0)
+ if (silc_buffer_sformat(stack, buf,
+ SILC_STR_UI_INT(SILC_PRIVATE_KEY_VERSION_1),
+ SILC_STR_UI_INT(e_len),
+ SILC_STR_UI_XNSTRING(eb, e_len),
+ SILC_STR_UI_INT(n_len),
+ SILC_STR_UI_XNSTRING(nb, n_len),
+ SILC_STR_UI_INT(d_len),
+ SILC_STR_UI_XNSTRING(db, d_len),
+ SILC_STR_UI_INT(dp_len),
+ SILC_STR_UI_XNSTRING(dpb, dp_len),
+ SILC_STR_UI_INT(dq_len),
+ SILC_STR_UI_XNSTRING(dqb, dq_len),
+ SILC_STR_UI_INT(qp_len),
+ SILC_STR_UI_XNSTRING(qpb, qp_len),
+ SILC_STR_UI_INT(p_len),
+ SILC_STR_UI_XNSTRING(pb, p_len),
+ SILC_STR_UI_INT(q_len),
+ SILC_STR_UI_XNSTRING(qb, q_len),
+ SILC_STR_END) < 0)
goto err;
key = silc_buffer_steal(buf, &key_len);
- silc_buffer_free(buf);
+ silc_buffer_sfree(stack, buf);
silc_free(nb);
silc_free(eb);
silc_free(db);
silc_free(pb);
silc_free(qb);
- } else if (!strcmp(pkcs->name, "dsa")) {
+ } else if (!strcmp(alg->name, "dsa")) {
SILC_NOT_IMPLEMENTED("SILC DSA Private Key");
goto err;
}
/* Encode SILC private key */
- totlen = 2 + strlen(pkcs->name) + key_len;
- buf = silc_buffer_alloc_size(totlen);
+ totlen = 2 + strlen(alg->name) + key_len;
+ buf = silc_buffer_salloc_size(stack, totlen);
if (!buf)
goto err;
- if (silc_buffer_format(buf,
- SILC_STR_UI_SHORT(strlen(pkcs->name)),
- SILC_STR_UI32_STRING(pkcs->name),
- SILC_STR_UI_XNSTRING(key, key_len),
- SILC_STR_END) < 0)
+ if (silc_buffer_sformat(stack, buf,
+ SILC_STR_UI_SHORT(strlen(alg->name)),
+ SILC_STR_UI32_STRING(alg->name),
+ SILC_STR_UI_XNSTRING(key, key_len),
+ SILC_STR_END) < 0)
goto err;
ret = silc_buffer_steal(buf, ret_len);
- silc_buffer_free(buf);
- silc_free(prv);
- silc_free(key);
+ silc_buffer_sfree(stack, buf);
+ silc_sfree(stack, prv);
+ silc_sfree(stack, key);
silc_asn1_free(asn1);
return ret;
err:
- silc_free(prv);
- silc_free(key);
- if (buf)
- silc_buffer_free(buf);
+ silc_sfree(stack, prv);
+ silc_sfree(stack, key);
+ silc_buffer_sfree(stack, buf);
return NULL;
}
/* Return key length */
-SilcUInt32 silc_pkcs_silc_private_key_bitlen(void *private_key)
+SilcUInt32
+silc_pkcs_silc_private_key_bitlen(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key)
{
SilcSILCPrivateKey silc_privkey = private_key;
- return silc_privkey->pkcs->private_key_bitlen(silc_privkey->private_key);
+ return silc_privkey->pkcs->private_key_bitlen(silc_privkey->pkcs,
+ silc_privkey->private_key);
}
/* Frees private key */
-void silc_pkcs_silc_private_key_free(void *private_key)
+void silc_pkcs_silc_private_key_free(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key)
{
SilcSILCPrivateKey silc_privkey = private_key;
- silc_privkey->pkcs->private_key_free(silc_privkey->private_key);
-
+ silc_privkey->pkcs->private_key_free(silc_privkey->pkcs,
+ silc_privkey->private_key);
silc_free(silc_privkey);
}
/* Encrypts as specified in SILC protocol specification */
-SilcBool silc_pkcs_silc_encrypt(void *public_key,
- unsigned char *src,
- SilcUInt32 src_len,
- unsigned char *dst,
- SilcUInt32 dst_size,
- SilcUInt32 *ret_dst_len,
- SilcRng rng)
+SilcAsyncOperation
+silc_pkcs_silc_encrypt(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcRng rng,
+ SilcPKCSEncryptCb encrypt_cb,
+ void *context)
{
SilcSILCPublicKey silc_pubkey = public_key;
- if (!silc_pubkey->pkcs->encrypt)
- return FALSE;
+ if (!silc_pubkey->pkcs->encrypt) {
+ encrypt_cb(FALSE, NULL, 0, context);
+ return NULL;
+ }
- return silc_pubkey->pkcs->encrypt(silc_pubkey->public_key,
- src, src_len,
- dst, dst_size, ret_dst_len, rng);
+ return silc_pubkey->pkcs->encrypt(silc_pubkey->pkcs,
+ silc_pubkey->public_key,
+ src, src_len, rng, encrypt_cb, context);
}
/* Decrypts as specified in SILC protocol specification */
-SilcBool silc_pkcs_silc_decrypt(void *private_key,
- unsigned char *src,
- SilcUInt32 src_len,
- unsigned char *dst,
- SilcUInt32 dst_size,
- SilcUInt32 *ret_dst_len)
+SilcAsyncOperation
+silc_pkcs_silc_decrypt(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcPKCSDecryptCb decrypt_cb,
+ void *context)
{
SilcSILCPrivateKey silc_privkey = private_key;
- if (!silc_privkey->pkcs->decrypt)
- return FALSE;
+ if (!silc_privkey->pkcs->decrypt) {
+ decrypt_cb(FALSE, NULL, 0, context);
+ return NULL;
+ }
- return silc_privkey->pkcs->decrypt(silc_privkey->private_key,
- src, src_len,
- dst, dst_size, ret_dst_len);
+ return silc_privkey->pkcs->decrypt(silc_privkey->pkcs,
+ silc_privkey->private_key,
+ src, src_len, decrypt_cb, context);
}
/* Signs as specified in SILC protocol specification */
-SilcBool silc_pkcs_silc_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)
+SilcAsyncOperation
+silc_pkcs_silc_sign(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcBool compute_hash,
+ SilcHash hash,
+ SilcPKCSSignCb sign_cb,
+ void *context)
{
SilcSILCPrivateKey silc_privkey = private_key;
- if (!silc_privkey->pkcs->sign)
- return FALSE;
+ if (!silc_privkey->pkcs->sign) {
+ sign_cb(FALSE, NULL, 0, context);
+ return NULL;
+ }
- return silc_privkey->pkcs->sign(silc_privkey->private_key,
+ return silc_privkey->pkcs->sign(silc_privkey->pkcs,
+ silc_privkey->private_key,
src, src_len,
- signature, signature_size,
- ret_signature_len, compute_hash, hash);
+ compute_hash, hash,
+ sign_cb, context);
}
/* Verifies as specified in SILC protocol specification */
-SilcBool silc_pkcs_silc_verify(void *public_key,
- unsigned char *signature,
- SilcUInt32 signature_len,
- unsigned char *data,
- SilcUInt32 data_len,
- SilcHash hash)
+SilcAsyncOperation
+silc_pkcs_silc_verify(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key,
+ unsigned char *signature,
+ SilcUInt32 signature_len,
+ unsigned char *data,
+ SilcUInt32 data_len,
+ SilcHash hash,
+ SilcPKCSVerifyCb verify_cb,
+ void *context)
{
SilcSILCPublicKey silc_pubkey = public_key;
- if (!silc_pubkey->pkcs->verify)
- return FALSE;
+ if (!silc_pubkey->pkcs->verify) {
+ verify_cb(FALSE, context);
+ return NULL;
+ }
- return silc_pubkey->pkcs->verify(silc_pubkey->public_key,
+ return silc_pubkey->pkcs->verify(silc_pubkey->pkcs,
+ silc_pubkey->public_key,
signature, signature_len,
- data, data_len, hash);
+ data, data_len, hash,
+ verify_cb, context);
}
* Protocol says that at least username and host must be provided.
* Caller must free the returned identifier string.
*
+ * If `stack' is non-NULL the returned string is allocated from `stack'.
+ *
***/
-char *silc_pkcs_silc_encode_identifier(char *username, char *host,
+char *silc_pkcs_silc_encode_identifier(SilcStack stack,
+ char *username, char *host,
char *realname, char *email,
char *org, char *country,
char *version);
#define SILC_PKCS_PRIVATE_KEYFILE_BEGIN "-----BEGIN SILC PRIVATE KEY-----\n"
#define SILC_PKCS_PRIVATE_KEYFILE_END "\n-----END SILC PRIVATE KEY-----\n"
-const SilcPKCSAlgorithm *silc_pkcs_silc_get_algorithm(void *public_key);
-SilcBool silc_pkcs_silc_import_public_key_file(unsigned char *filedata,
- SilcUInt32 filedata_len,
- SilcPKCSFileEncoding encoding,
- void **ret_public_key);
-int silc_pkcs_silc_import_public_key(unsigned char *key,
+const SilcPKCSAlgorithm *
+silc_pkcs_silc_get_algorithm(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key);
+SilcBool
+silc_pkcs_silc_import_public_key_file(const struct SilcPKCSObjectStruct *pkcs,
+ unsigned char *filedata,
+ SilcUInt32 filedata_len,
+ SilcPKCSFileEncoding encoding,
+ void **ret_public_key);
+int silc_pkcs_silc_import_public_key(const struct SilcPKCSObjectStruct *pkcs,
+ void *key,
SilcUInt32 key_len,
void **ret_public_key);
unsigned char *
-silc_pkcs_silc_export_public_key_file(void *public_key,
+silc_pkcs_silc_export_public_key_file(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ void *public_key,
SilcPKCSFileEncoding encoding,
SilcUInt32 *ret_len);
-unsigned char *silc_pkcs_silc_export_public_key(void *public_key,
- SilcUInt32 *ret_len);
-SilcUInt32 silc_pkcs_silc_public_key_bitlen(void *public_key);
-void *silc_pkcs_silc_public_key_copy(void *public_key);
-SilcBool silc_pkcs_silc_public_key_compare(void *key1, void *key2);
-void silc_pkcs_silc_public_key_free(void *public_key);
-SilcBool silc_pkcs_silc_import_private_key_file(unsigned char *filedata,
- SilcUInt32 filedata_len,
- const char *passphrase,
- SilcUInt32 passphrase_len,
- SilcPKCSFileEncoding encoding,
- void **ret_private_key);
-int silc_pkcs_silc_import_private_key(unsigned char *key,
+unsigned char *
+silc_pkcs_silc_export_public_key(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ void *public_key,
+ SilcUInt32 *ret_len);
+SilcUInt32
+silc_pkcs_silc_public_key_bitlen(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key);
+void *silc_pkcs_silc_public_key_copy(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key);
+SilcBool
+silc_pkcs_silc_public_key_compare(const struct SilcPKCSObjectStruct *pkcs,
+ void *key1, void *key2);
+void silc_pkcs_silc_public_key_free(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key);
+SilcBool
+silc_pkcs_silc_import_private_key_file(const struct SilcPKCSObjectStruct *pkcs,
+ unsigned char *filedata,
+ SilcUInt32 filedata_len,
+ const char *passphrase,
+ SilcUInt32 passphrase_len,
+ SilcPKCSFileEncoding encoding,
+ void **ret_private_key);
+int silc_pkcs_silc_import_private_key(const struct SilcPKCSObjectStruct *pkcs,
+ void *key,
SilcUInt32 key_len,
void **ret_private_key);
unsigned char *
-silc_pkcs_silc_export_private_key_file(void *private_key,
+silc_pkcs_silc_export_private_key_file(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ void *private_key,
const char *passphrase,
SilcUInt32 passphrase_len,
SilcPKCSFileEncoding encoding,
SilcRng rng,
SilcUInt32 *ret_len);
-unsigned char *silc_pkcs_silc_export_private_key(void *private_key,
- SilcUInt32 *ret_len);
-SilcUInt32 silc_pkcs_silc_private_key_bitlen(void *private_key);
-void silc_pkcs_silc_private_key_free(void *private_key);
-SilcBool silc_pkcs_silc_encrypt(void *public_key,
- unsigned char *src,
- SilcUInt32 src_len,
- unsigned char *dst,
- SilcUInt32 dst_size,
- SilcUInt32 *ret_dst_len,
- SilcRng rng);
-SilcBool silc_pkcs_silc_decrypt(void *private_key,
- unsigned char *src,
- SilcUInt32 src_len,
- unsigned char *dst,
- SilcUInt32 dst_size,
- SilcUInt32 *ret_dst_len);
-SilcBool silc_pkcs_silc_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 silc_pkcs_silc_verify(void *public_key,
- unsigned char *signature,
- SilcUInt32 signature_len,
- unsigned char *data,
- SilcUInt32 data_len,
- SilcHash hash);
+unsigned char *
+silc_pkcs_silc_export_private_key(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ void *private_key,
+ SilcUInt32 *ret_len);
+SilcUInt32
+silc_pkcs_silc_private_key_bitlen(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key);
+void silc_pkcs_silc_private_key_free(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key);
+SilcAsyncOperation
+silc_pkcs_silc_encrypt(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcRng rng,
+ SilcPKCSEncryptCb encrypt_cb,
+ void *context);
+SilcAsyncOperation
+silc_pkcs_silc_decrypt(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcPKCSDecryptCb decrypt_cb,
+ void *context);
+SilcAsyncOperation
+silc_pkcs_silc_sign(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcBool compute_hash,
+ SilcHash hash,
+ SilcPKCSSignCb sign_cb,
+ void *context);
+SilcAsyncOperation
+silc_pkcs_silc_verify(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key,
+ unsigned char *signature,
+ SilcUInt32 signature_len,
+ unsigned char *data,
+ SilcUInt32 data_len,
+ SilcHash hash,
+ SilcPKCSVerifyCb verify_cb,
+ void *context);
#endif /* SILCPK_I_H */
}
};
-/* Register a new PKCS into SILC. */
+/* Register a new PKCS */
SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs)
{
return TRUE;
}
-/* Unregister a PKCS from the SILC. */
+/* Unregister a PKCS */
SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs)
{
SilcBool silc_pkcs_register_default(void)
{
-#ifndef SILC_SYMBIAN
- int i;
-
- for (i = 0; silc_default_pkcs[i].type; i++)
- silc_pkcs_register(&(silc_default_pkcs[i]));
-
- for (i = 0; silc_default_pkcs_alg[i].name; i++)
- silc_pkcs_algorithm_register(&(silc_default_pkcs_alg[i]));
-
-#endif /* SILC_SYMBIAN */
+ /* We use builtin PKCS and algorithms */
return TRUE;
}
+/* Unregister all PKCS and algorithms */
+
SilcBool silc_pkcs_unregister_all(void)
{
#ifndef SILC_SYMBIAN
char *silc_pkcs_get_supported(void)
{
- SilcPKCSAlgorithm *entry;
+ SilcPKCSAlgorithm *entry, *entry2;
char *list = NULL;
- int len = 0;
+ int i, len = 0;
#ifndef SILC_SYMBIAN
if (silc_pkcs_alg_list) {
len++;
}
}
-#else
- {
- int i;
- for (i = 0; silc_default_pkcs_alg[i].name; i++) {
- entry = (SilcPKCSAlgorithm *)&(silc_default_pkcs_alg[i]);
- len += strlen(entry->name);
- list = silc_realloc(list, len + 1);
- if (!list)
- return NULL;
+#endif /* SILC_SYMBIAN */
- memcpy(list + (len - strlen(entry->name)),
- entry->name, strlen(entry->name));
- memcpy(list + len, ",", 1);
- len++;
+ for (i = 0; silc_default_pkcs_alg[i].name; i++) {
+ entry = (SilcPKCSAlgorithm *)&(silc_default_pkcs_alg[i]);
+
+ if (silc_pkcs_alg_list) {
+ silc_dlist_start(silc_pkcs_alg_list);
+ while ((entry2 = silc_dlist_get(silc_pkcs_alg_list)) != SILC_LIST_END) {
+ if (!strcmp(entry2->name, entry->name))
+ break;
+ }
+ if (entry2)
+ continue;
}
+
+ len += strlen(entry->name);
+ list = silc_realloc(list, len + 1);
+ if (!list)
+ return NULL;
+
+ memcpy(list + (len - strlen(entry->name)),
+ entry->name, strlen(entry->name));
+ memcpy(list + len, ",", 1);
+ len++;
}
-#endif /* SILC_SYMBIAN */
list[len - 1] = 0;
const SilcPKCSObject *silc_pkcs_find_pkcs(SilcPKCSType type)
{
SilcPKCSObject *entry;
+ int i;
#ifndef SILC_SYMBIAN
if (silc_pkcs_list) {
return (const SilcPKCSObject *)entry;
}
}
-#else
- {
- int i;
- for (i = 0; silc_default_pkcs[i].type; i++) {
- entry = (SilcPKCSObject *)&(silc_default_pkcs[i]);
- if (entry->type == type)
- return (const SilcPKCSObject *)entry;
- }
- }
#endif /* SILC_SYMBIAN */
+ for (i = 0; silc_default_pkcs[i].type; i++) {
+ entry = (SilcPKCSObject *)&(silc_default_pkcs[i]);
+ if (entry->type == type)
+ return (const SilcPKCSObject *)entry;
+ }
+
return NULL;
}
const char *scheme)
{
SilcPKCSAlgorithm *entry;
+ int i;
#ifndef SILC_SYMBIAN
if (silc_pkcs_alg_list) {
return (const SilcPKCSAlgorithm *)entry;
}
}
-#else
- {
- int i;
- for (i = 0; silc_default_pkcs_alg[i].name; i++) {
- entry = (SilcPKCSAlgorithm *)&(silc_default_pkcs_alg[i]);
- if (!strcmp(entry->name, algorithm) &&
- (!scheme || !entry->scheme || !strcmp(entry->scheme, scheme)))
- return (const SilcPKCSAlgorithm *)entry;
- }
- }
#endif /* SILC_SYMBIAN */
+ for (i = 0; silc_default_pkcs_alg[i].name; i++) {
+ entry = (SilcPKCSAlgorithm *)&(silc_default_pkcs_alg[i]);
+ if (!strcmp(entry->name, algorithm) &&
+ (!scheme || !entry->scheme || !strcmp(entry->scheme, scheme)))
+ return (const SilcPKCSAlgorithm *)entry;
+ }
+
return NULL;
}
const SilcPKCSAlgorithm *silc_pkcs_get_algorithm(void *key)
{
SilcPublicKey public_key = key;
- return public_key->pkcs->get_algorithm(public_key->public_key);
+ return public_key->pkcs->get_algorithm(public_key->pkcs,
+ public_key->public_key);
}
/* Return algorithm name */
}
/* Import the PKCS public key */
- if (!pkcs->import_public_key(key, key_len, &public_key->public_key)) {
+ if (!pkcs->import_public_key(pkcs, key, key_len, &public_key->public_key)) {
silc_free(public_key);
return FALSE;
}
void silc_pkcs_public_key_free(SilcPublicKey public_key)
{
- public_key->pkcs->public_key_free(public_key->public_key);
+ public_key->pkcs->public_key_free(public_key->pkcs, public_key->public_key);
silc_free(public_key);
}
/* Exports public key */
-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)
{
- return public_key->pkcs->export_public_key(public_key->public_key,
- ret_len);
+ return public_key->pkcs->export_public_key(public_key->pkcs, stack,
+ public_key->public_key, ret_len);
}
/* Return key length */
SilcUInt32 silc_pkcs_public_key_get_len(SilcPublicKey public_key)
{
- return public_key->pkcs->public_key_bitlen(public_key->public_key);
+ return public_key->pkcs->public_key_bitlen(public_key->pkcs,
+ public_key->public_key);
}
/* Returns internal PKCS public key context */
}
/* Import the PKCS private key */
- if (!pkcs->import_private_key(key, key_len, &private_key->private_key)) {
+ if (!pkcs->import_private_key(pkcs, key, key_len,
+ &private_key->private_key)) {
silc_free(private_key);
return FALSE;
}
SilcUInt32 silc_pkcs_private_key_get_len(SilcPrivateKey private_key)
{
- return private_key->pkcs->private_key_bitlen(private_key->private_key);
+ return private_key->pkcs->private_key_bitlen(private_key->pkcs,
+ private_key->private_key);
}
/* Frees the private key */
void silc_pkcs_private_key_free(SilcPrivateKey private_key)
{
- private_key->pkcs->private_key_free(private_key->private_key);
+ private_key->pkcs->private_key_free(private_key->pkcs,
+ private_key->private_key);
silc_free(private_key);
}
/* Encrypts */
-SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
- unsigned char *src, SilcUInt32 src_len,
- unsigned char *dst, SilcUInt32 dst_size,
- SilcUInt32 *dst_len, SilcRng rng)
+SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
+ unsigned char *src, SilcUInt32 src_len,
+ SilcRng rng,
+ SilcPKCSEncryptCb encrypt_cb,
+ void *context)
{
- return public_key->pkcs->encrypt(public_key->public_key, src, src_len,
- dst, dst_size, dst_len, rng);
+ return public_key->pkcs->encrypt(public_key->pkcs,
+ public_key->public_key, src, src_len,
+ rng, encrypt_cb, context);
}
/* Decrypts */
-SilcBool silc_pkcs_decrypt(SilcPrivateKey private_key,
- unsigned char *src, SilcUInt32 src_len,
- unsigned char *dst, SilcUInt32 dst_size,
- SilcUInt32 *dst_len)
+SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
+ unsigned char *src, SilcUInt32 src_len,
+ SilcPKCSDecryptCb decrypt_cb,
+ void *context)
{
- return private_key->pkcs->decrypt(private_key->private_key, src, src_len,
- dst, dst_size, dst_len);
+ return private_key->pkcs->decrypt(private_key->pkcs,
+ private_key->private_key, src, src_len,
+ decrypt_cb, context);
}
/* Generates signature */
-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)
-{
- return private_key->pkcs->sign(private_key->private_key, src, src_len,
- dst, dst_size, dst_len, compute_hash, hash);
+SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcBool compute_hash,
+ SilcHash hash,
+ SilcPKCSSignCb sign_cb,
+ void *context)
+{
+ return private_key->pkcs->sign(private_key->pkcs,
+ private_key->private_key, src, src_len,
+ compute_hash, hash, sign_cb, context);
}
/* Verifies signature */
-SilcBool silc_pkcs_verify(SilcPublicKey public_key,
- unsigned char *signature,
- SilcUInt32 signature_len,
- unsigned char *data,
- SilcUInt32 data_len, SilcHash hash)
-{
- return public_key->pkcs->verify(public_key->public_key, signature,
- signature_len, data, data_len, hash);
+SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
+ unsigned char *signature,
+ SilcUInt32 signature_len,
+ unsigned char *data,
+ SilcUInt32 data_len,
+ SilcHash hash,
+ SilcPKCSVerifyCb verify_cb,
+ void *context)
+{
+ return public_key->pkcs->verify(public_key->pkcs,
+ public_key->public_key, signature,
+ signature_len, data, data_len, hash,
+ verify_cb, context);
}
/* Compares two public keys and returns TRUE if they are same key, and
if (key1->pkcs->type != key2->pkcs->type)
return FALSE;
- return key1->pkcs->public_key_compare(key1->public_key, key2->public_key);
+ return key1->pkcs->public_key_compare(key1->pkcs,
+ key1->public_key, key2->public_key);
}
/* Copies the public key indicated by `public_key' and returns new allocated
return NULL;
key->pkcs = public_key->pkcs;
- key->public_key = public_key->pkcs->public_key_copy(public_key->public_key);
+ key->public_key = public_key->pkcs->public_key_copy(public_key->pkcs,
+ public_key->public_key);
if (!key->public_key) {
silc_free(key);
return NULL;
if (!public_key->pkcs)
continue;
- if (public_key->pkcs->import_public_key_file(data, data_len,
+ if (public_key->pkcs->import_public_key_file(public_key->pkcs,
+ data, data_len,
SILC_PKCS_FILE_BASE64,
&public_key->public_key)) {
silc_free(data);
return TRUE;
}
- if (public_key->pkcs->import_public_key_file(data, data_len,
+ if (public_key->pkcs->import_public_key_file(public_key->pkcs,
+ data, data_len,
SILC_PKCS_FILE_BIN,
&public_key->public_key)) {
silc_free(data);
{
unsigned char *data;
SilcUInt32 data_len;
+ SilcStack stack;
+
+ stack = silc_stack_alloc(2048, silc_crypto_stack());
/* Export the public key file */
- data = public_key->pkcs->export_public_key_file(public_key->public_key,
+ data = public_key->pkcs->export_public_key_file(public_key->pkcs,
+ stack,
+ public_key->public_key,
encoding, &data_len);
- if (!data)
+ if (!data) {
+ silc_stack_free(stack);
return FALSE;
+ }
/* Write to file */
if (silc_file_writefile(filename, data, data_len)) {
- silc_free(data);
+ silc_sfree(stack, data);
+ silc_stack_free(stack);
return FALSE;
}
- silc_free(data);
+ silc_sfree(stack, data);
+ silc_stack_free(stack);
return TRUE;
}
continue;
if (private_key->pkcs->import_private_key_file(
+ private_key->pkcs,
data, data_len,
passphrase,
passphrase_len,
}
if (private_key->pkcs->import_private_key_file(
+ private_key->pkcs,
data, data_len,
passphrase,
passphrase_len,
{
unsigned char *data;
SilcUInt32 data_len;
+ SilcStack stack;
+
+ stack = silc_stack_alloc(2048, silc_crypto_stack());
/* Export the private key file */
- data = private_key->pkcs->export_private_key_file(private_key->private_key,
+ data = private_key->pkcs->export_private_key_file(private_key->pkcs, stack,
+ private_key->private_key,
passphrase,
passphrase_len,
encoding, rng, &data_len);
- if (!data)
+ if (!data) {
+ silc_stack_free(stack);
return FALSE;
+ }
/* Write to file */
if (silc_file_writefile(filename, data, data_len)) {
- silc_free(data);
+ silc_sfree(stack, data);
+ silc_stack_free(stack);
return FALSE;
}
- silc_free(data);
+ silc_sfree(stack, data);
+ silc_stack_free(stack);
return TRUE;
}
+
+/* Hash public key of any type. */
+
+SilcUInt32 silc_hash_public_key(void *key, void *user_context)
+{
+ SilcPublicKey public_key = key;
+ unsigned char *pk;
+ SilcUInt32 pk_len;
+ SilcUInt32 hash = 0;
+ SilcStack stack = NULL;
+
+ if (silc_crypto_stack())
+ stack = silc_stack_alloc(2048, silc_crypto_stack());
+
+ pk = silc_pkcs_public_key_encode(stack, public_key, &pk_len);
+ if (!pk) {
+ silc_stack_free(stack);
+ return hash;
+ }
+
+ hash = silc_hash_data(pk, SILC_32_TO_PTR(pk_len));
+
+ silc_sfree(stack, pk);
+ silc_stack_free(stack);
+
+ return hash;
+}
+
+/* Compares two SILC Public keys. It may be used as SilcHashTable
+ comparison function. */
+
+SilcBool silc_hash_public_key_compare(void *key1, void *key2,
+ void *user_context)
+{
+ return silc_pkcs_public_key_compare(key1, key2);
+}
#define SILCPKCS_H
/* Forward declarations */
+typedef struct SilcPKCSAlgorithmStruct SilcPKCSAlgorithm;
typedef struct SilcPKCSObjectStruct SilcPKCSObject;
/****d* silccrypt/SilcPKCSAPI/SilcPKCSType
} 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);
+/****f* silccrypt/SilcPKCSAPI/SilcPKCSEncryptCb
+ *
+ * SYNOPSIS
+ *
+ * typedef void (*SilcPKCSEncryptCb)(SilcBool success,
+ * const unsigned char *encrypted,
+ * SilcUInt32 encrypted_len,
+ * void *context);
+ *
+ * DESCRIPTION
+ *
+ * Encryption callback. This callback is given as argument to the
+ * silc_pkcs_encrypt and the encrypted data is delivered to the caller
+ * in this callback. The `encrypted' is the encrypted data. If the
+ * `success' is FALSE the encryption operation failed.
+ *
+ ***/
+typedef void (*SilcPKCSEncryptCb)(SilcBool success,
+ const unsigned char *encrypted,
+ SilcUInt32 encrypted_len,
+ void *context);
+
+/****f* silccrypt/SilcPKCSAPI/SilcPKCSDecryptCb
+ *
+ * SYNOPSIS
+ *
+ * typedef void (*SilcPKCSDecryptCb)(SilcBool success,
+ * const unsigned char *decrypted,
+ * SilcUInt32 decrypted_len,
+ * void *context);
+ *
+ * DESCRIPTION
+ *
+ * Decryption callback. This callback is given as argument to the
+ * silc_pkcs_decrypt and the decrypted data is delivered to the caller
+ * in this callback. The `decrypted' is the decrypted data. If the
+ * `success' is FALSE the decryption operation failed.
+ *
+ ***/
+typedef void (*SilcPKCSDecryptCb)(SilcBool success,
+ const unsigned char *decrypted,
+ SilcUInt32 decrypted_len,
+ void *context);
- /* 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);
-};
+/****f* silccrypt/SilcPKCSAPI/SilcPKCSSignCb
+ *
+ * SYNOPSIS
+ *
+ * typedef void (*SilcPKCSSignCb)(SilcBool success,
+ * const unsigned char *signature,
+ * SilcUInt32 signature_len,
+ * void *context);
+ *
+ * DESCRIPTION
+ *
+ * Signature callback. This callback is given as argument to the
+ * silc_pkcs_sign and the digitally signed data is delivered to the caller
+ * in this callback. The `signature' is the signature data. If the
+ * `success' is FALSE the signature operation failed.
+ *
+ ***/
+typedef void (*SilcPKCSSignCb)(SilcBool success,
+ const unsigned char *signature,
+ SilcUInt32 signature_len,
+ void *context);
+
+/****f* silccrypt/SilcPKCSAPI/SilcPKCSVerifyCb
+ *
+ * SYNOPSIS
+ *
+ * typedef void (*SilcPKCSVerifyCb)(SilcBool success, void *context);
+ *
+ * DESCRIPTION
+ *
+ * Verification callback. This callback is given as argument to the
+ * silc_pkcs_verify and the result of the signature verification is
+ * deliver to the caller in this callback. If the `success' is FALSE
+ * the signature verification failed.
+ *
+ ***/
+typedef void (*SilcPKCSVerifyCb)(SilcBool success, void *context);
+
+#include "silcpkcs_i.h"
/* Marks for all PKCS in. This can be used in silc_pkcs_unregister to
unregister all PKCS at once. */
*
* DESCRIPTION
*
- * Registers a new PKCS Algorithm into crypto library. This function
+ * Registers a new PKCS Algorithm into crypto library. This function
* is used at the initialization of an application. All registered PKCS
* algorithms should be unregistered with silc_pkcs_unregister.
*
*
* 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
* 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
*
* SYNOPSIS
*
- * SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
- * unsigned char *src, SilcUInt32 src_len,
- * unsigned char *dst, SilcUInt32 dst_size,
- * SilcUInt32 *dst_len);
+ * SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
+ * unsigned char *src,
+ * SilcUInt32 src_len, SilcRng rng,
+ * SilcPKCSEncryptCb encrypt_cb,
+ * void *context);
*
* DESCRIPTION
*
- * Encrypts with the public key. Returns FALSE on error.
+ * 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.
*
***/
-SilcBool silc_pkcs_encrypt(SilcPublicKey public_key,
- unsigned char *src, SilcUInt32 src_len,
- unsigned char *dst, SilcUInt32 dst_size,
- SilcUInt32 *dst_len, SilcRng rng);
+SilcAsyncOperation silc_pkcs_encrypt(SilcPublicKey public_key,
+ unsigned char *src,
+ SilcUInt32 src_len, SilcRng rng,
+ SilcPKCSEncryptCb encrypt_cb,
+ void *context);
/****f* silccrypt/SilcPKCSAPI/silc_pkcs_decrypt
*
* SYNOPSIS
*
- * SilcBool silc_pkcs_decrypt(SilcPrivateKey private_key,
- * unsigned char *src, SilcUInt32 src_len,
- * unsigned char *dst, SilcUInt32 dst_size,
- * SilcUInt32 *dst_len);
+ * SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
+ * unsigned char *src,
+ * SilcUInt32 src_len,
+ * SilcPKCSDecryptCb decrypt_cb,
+ * void *context);
*
* DESCRIPTION
*
- * Decrypts with the private key. Returns FALSE on error.
+ * 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.
*
***/
-SilcBool silc_pkcs_decrypt(SilcPrivateKey private_key,
- unsigned char *src, SilcUInt32 src_len,
- unsigned char *dst, SilcUInt32 dst_size,
- SilcUInt32 *dst_len);
+SilcAsyncOperation silc_pkcs_decrypt(SilcPrivateKey private_key,
+ unsigned char *src, SilcUInt32 src_len,
+ SilcPKCSDecryptCb decrypt_cb,
+ void *context);
/****f* silccrypt/SilcPKCSAPI/silc_pkcs_sign
*
* SYNOPSIS
*
- * 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);
+ * SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
+ * unsigned char *src,
+ * SilcUInt32 src_len,
+ * SilcBool compute_hash,
+ * SilcHash hash,
+ * SilcPKCSSignCb sign_cb,
+ * void *context);
*
* 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. The `sign_cb' will be called
+ * to deliver the signature data. If `compute_hash' is TRUE the `hash'
+ * will be used to compute a message digest over the `src'. The `hash'
+ * must always be valid. The signature operation may be asynchronous if
+ * the `private_key' is accelerated private key. If this returns NULL the
+ * asynchronous operation cannot be controlled.
*
***/
-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);
+SilcAsyncOperation silc_pkcs_sign(SilcPrivateKey private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcBool compute_hash,
+ SilcHash hash,
+ SilcPKCSSignCb sign_cb,
+ void *context);
/****f* silccrypt/SilcPKCSAPI/silc_pkcs_verify
*
* SYNOPSIS
*
- * SilcBool silc_pkcs_verify(SilcPublicKey public_key,
- * unsigned char *signature,
- * SilcUInt32 signature_len,
- * unsigned char *data,
- * SilcUInt32 data_len, SilcHash hash);
+ * SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
+ * unsigned char *signature,
+ * SilcUInt32 signature_len,
+ * unsigned char *data,
+ * SilcUInt32 data_len,
+ * SilcHash hash,
+ * SilcPKCSVerifyCb verify_cb,
+ * void *context);
*
* DESCRIPTION
*
- * 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 `verify_cb' will be called to deliver the
+ * result of the verification process. The 'signature' is verified against
+ * the 'data'. If the `hash' is non-NULL then the `data' will hashed
+ * before verification. If the `hash' is NULL, then the hash algorithm
+ * to be used is retrieved from the signature. If it isn't present in the
+ * signature the verification is done as is without hashing. If this
+ * returns NULL the asynchronous operation cannot be controlled.
*
***/
-SilcBool silc_pkcs_verify(SilcPublicKey public_key,
- unsigned char *signature,
- SilcUInt32 signature_len,
- unsigned char *data,
- SilcUInt32 data_len, SilcHash hash);
+SilcAsyncOperation silc_pkcs_verify(SilcPublicKey public_key,
+ unsigned char *signature,
+ SilcUInt32 signature_len,
+ unsigned char *data,
+ SilcUInt32 data_len,
+ SilcHash hash,
+ SilcPKCSVerifyCb verify_cb,
+ void *context);
/****f* silccrypt/SilcPKCSAPI/silc_pkcs_load_public_key
*
SilcPKCSFileEncoding encoding,
SilcRng rng);
+/****f* silccrypt/SilcPKCSAPI/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/SilcPKCSAPI/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 */
/* Generates RSA key pair. */
-SilcBool silc_pkcs1_generate_key(SilcUInt32 keylen,
+SilcBool silc_pkcs1_generate_key(const struct SilcPKCSAlgorithmStruct *pkcs,
+ SilcUInt32 keylen,
SilcRng rng,
void **ret_public_key,
void **ret_private_key)
/* Import PKCS #1 compliant public key */
-int silc_pkcs1_import_public_key(unsigned char *key,
+int silc_pkcs1_import_public_key(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *key,
SilcUInt32 key_len,
void **ret_public_key)
{
/* Export PKCS #1 compliant public key */
-unsigned char *silc_pkcs1_export_public_key(void *public_key,
- SilcUInt32 *ret_len)
+unsigned char *
+silc_pkcs1_export_public_key(const struct SilcPKCSAlgorithmStruct *pkcs,
+ SilcStack stack,
+ void *public_key,
+ SilcUInt32 *ret_len)
{
RsaPublicKey *key = public_key;
SilcAsn1 asn1 = NULL;
SilcBufferStruct alg_key;
unsigned char *ret;
- asn1 = silc_asn1_alloc(NULL);
+ asn1 = silc_asn1_alloc(stack);
if (!asn1)
goto err;
/* Returns key length */
-SilcUInt32 silc_pkcs1_public_key_bitlen(void *public_key)
+SilcUInt32
+silc_pkcs1_public_key_bitlen(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key)
{
RsaPublicKey *key = public_key;
return key->bits;
/* Copy public key */
-void *silc_pkcs1_public_key_copy(void *public_key)
+void *silc_pkcs1_public_key_copy(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key)
{
RsaPublicKey *key = public_key, *new_key;
/* Compare public keys */
-SilcBool silc_pkcs1_public_key_compare(void *key1, void *key2)
+SilcBool
+silc_pkcs1_public_key_compare(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *key1, void *key2)
{
RsaPublicKey *k1 = key1, *k2 = key2;
/* Frees public key */
-void silc_pkcs1_public_key_free(void *public_key)
+void silc_pkcs1_public_key_free(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key)
{
RsaPublicKey *key = public_key;
/* Import PKCS #1 compliant private key */
-int silc_pkcs1_import_private_key(unsigned char *key,
+int silc_pkcs1_import_private_key(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *key,
SilcUInt32 key_len,
void **ret_private_key)
{
/* Export PKCS #1 compliant private key */
-unsigned char *silc_pkcs1_export_private_key(void *private_key,
- SilcUInt32 *ret_len)
+unsigned char *
+silc_pkcs1_export_private_key(const struct SilcPKCSAlgorithmStruct *pkcs,
+ SilcStack stack,
+ void *private_key,
+ SilcUInt32 *ret_len)
{
RsaPrivateKey *key = private_key;
SilcAsn1 asn1;
SilcBufferStruct alg_key;
unsigned char *ret;
- asn1 = silc_asn1_alloc(NULL);
+ asn1 = silc_asn1_alloc(stack);
if (!asn1)
return FALSE;
/* Returns key length */
-SilcUInt32 silc_pkcs1_private_key_bitlen(void *private_key)
+SilcUInt32
+silc_pkcs1_private_key_bitlen(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key)
{
RsaPrivateKey *key = private_key;
return key->bits;
/* Frees private key */
-void silc_pkcs1_private_key_free(void *private_key)
+void silc_pkcs1_private_key_free(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key)
{
RsaPrivateKey *key = private_key;
/* PKCS #1 RSA routines */
-SilcBool silc_pkcs1_encrypt(void *public_key,
- unsigned char *src,
- SilcUInt32 src_len,
- unsigned char *dst,
- SilcUInt32 dst_size,
- SilcUInt32 *ret_dst_len,
- SilcRng rng)
+SilcAsyncOperation
+silc_pkcs1_encrypt(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcRng rng,
+ SilcPKCSEncryptCb encrypt_cb,
+ void *context)
{
RsaPublicKey *key = public_key;
SilcMPInt mp_tmp;
SilcMPInt mp_dst;
unsigned char padded[2048 + 1];
SilcUInt32 len = (key->bits + 7) / 8;
+ SilcStack stack;
- if (sizeof(padded) < len)
- return FALSE;
- if (dst_size < len)
- return FALSE;
+ if (sizeof(padded) < len) {
+ encrypt_cb(FALSE, NULL, 0, context);
+ return NULL;
+ }
/* Pad data */
if (!silc_pkcs1_encode(SILC_PKCS1_BT_PUB, src, src_len,
- padded, len, rng))
- return FALSE;
+ padded, len, rng)) {
+ encrypt_cb(FALSE, NULL, 0, context);
+ return NULL;
+ }
+
+ stack = silc_stack_alloc(2048, silc_crypto_stack());
- silc_mp_init(&mp_tmp);
- silc_mp_init(&mp_dst);
+ silc_mp_sinit(stack, &mp_tmp);
+ silc_mp_sinit(stack, &mp_dst);
/* Data to MP */
silc_mp_bin2mp(padded, len, &mp_tmp);
silc_rsa_public_operation(key, &mp_tmp, &mp_dst);
/* MP to data */
- silc_mp_mp2bin_noalloc(&mp_dst, dst, len);
- *ret_dst_len = len;
+ silc_mp_mp2bin_noalloc(&mp_dst, padded, len);
+
+ /* Deliver result */
+ encrypt_cb(TRUE, padded, len, context);
memset(padded, 0, sizeof(padded));
- silc_mp_uninit(&mp_tmp);
- silc_mp_uninit(&mp_dst);
+ silc_mp_suninit(stack, &mp_tmp);
+ silc_mp_suninit(stack, &mp_dst);
+ silc_stack_free(stack);
- return TRUE;
+ return NULL;
}
-SilcBool silc_pkcs1_decrypt(void *private_key,
- unsigned char *src,
- SilcUInt32 src_len,
- unsigned char *dst,
- SilcUInt32 dst_size,
- SilcUInt32 *ret_dst_len)
+SilcAsyncOperation
+silc_pkcs1_decrypt(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcPKCSDecryptCb decrypt_cb,
+ void *context)
{
RsaPrivateKey *key = private_key;
SilcMPInt mp_tmp;
SilcMPInt mp_dst;
unsigned char *padded, unpadded[2048 + 1];
- SilcUInt32 padded_len;
+ SilcUInt32 padded_len, dst_len;
+ SilcStack stack;
- if (dst_size < (key->bits + 7) / 8)
- return FALSE;
+ if (sizeof(unpadded) < (key->bits + 7) / 8) {
+ decrypt_cb(FALSE, NULL, 0, context);
+ return NULL;
+ }
+
+ stack = silc_stack_alloc(2048, silc_crypto_stack());
- silc_mp_init(&mp_tmp);
- silc_mp_init(&mp_dst);
+ silc_mp_sinit(stack, &mp_tmp);
+ silc_mp_sinit(stack, &mp_dst);
/* Data to MP */
silc_mp_bin2mp(src, src_len, &mp_tmp);
/* Unpad data */
if (!silc_pkcs1_decode(SILC_PKCS1_BT_PUB, padded, padded_len,
- unpadded, sizeof(unpadded), ret_dst_len)) {
+ unpadded, sizeof(unpadded), &dst_len)) {
memset(padded, 0, padded_len);
silc_free(padded);
- silc_mp_uninit(&mp_tmp);
- silc_mp_uninit(&mp_dst);
- return FALSE;
+ silc_mp_suninit(stack, &mp_tmp);
+ silc_mp_suninit(stack, &mp_dst);
+ decrypt_cb(FALSE, NULL, 0, context);
+ return NULL;
}
- /* Copy to destination */
- memcpy(dst, unpadded, *ret_dst_len);
+ /* Deliver result */
+ decrypt_cb(TRUE, unpadded, dst_len, context);
memset(padded, 0, padded_len);
memset(unpadded, 0, sizeof(unpadded));
silc_free(padded);
- silc_mp_uninit(&mp_tmp);
- silc_mp_uninit(&mp_dst);
+ silc_mp_suninit(stack, &mp_tmp);
+ silc_mp_suninit(stack, &mp_dst);
+ silc_stack_free(stack);
- return TRUE;
+ return NULL;
}
/* PKCS #1 sign with appendix, hash OID included in the signature */
-SilcBool silc_pkcs1_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)
+SilcAsyncOperation
+silc_pkcs1_sign(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcBool compute_hash,
+ SilcHash hash,
+ SilcPKCSSignCb sign_cb,
+ void *context)
{
RsaPrivateKey *key = private_key;
unsigned char padded[2048 + 1], hashr[SILC_HASH_MAXLEN];
SilcBufferStruct di;
SilcUInt32 len = (key->bits + 7) / 8;
const char *oid;
+ SilcStack stack;
SilcAsn1 asn1;
SILC_LOG_DEBUG(("Sign"));
- if (sizeof(padded) < len)
- return FALSE;
- if (signature_size < len)
- return FALSE;
+ if (sizeof(padded) < len) {
+ sign_cb(FALSE, NULL, 0, context);
+ return NULL;
+ }
oid = silc_hash_get_oid(hash);
- if (!oid)
- return FALSE;
+ if (!oid) {
+ sign_cb(FALSE, NULL, 0, context);
+ return NULL;
+ }
- asn1 = silc_asn1_alloc(NULL);
- if (!asn1)
- return FALSE;
+ stack = silc_stack_alloc(2048, silc_crypto_stack());
+
+ asn1 = silc_asn1_alloc(stack);
+ if (!asn1) {
+ silc_stack_free(stack);
+ sign_cb(FALSE, NULL, 0, context);
+ return NULL;
+ }
/* Compute hash */
if (compute_hash) {
SILC_ASN1_SEQUENCE,
SILC_ASN1_SEQUENCE,
SILC_ASN1_OID(oid),
- SILC_ASN1_NULL,
+ SILC_ASN1_NULL(TRUE),
SILC_ASN1_END,
SILC_ASN1_OCTET_STRING(src, src_len),
SILC_ASN1_END, SILC_ASN1_END)) {
silc_asn1_free(asn1);
- return FALSE;
+ silc_stack_free(stack);
+ sign_cb(FALSE, NULL, 0, context);
+ return NULL;
}
SILC_LOG_HEXDUMP(("DigestInfo"), silc_buffer_data(&di),
silc_buffer_len(&di));
if (!silc_pkcs1_encode(SILC_PKCS1_BT_PRV1, silc_buffer_data(&di),
silc_buffer_len(&di), padded, len, NULL)) {
silc_asn1_free(asn1);
- return FALSE;
+ silc_stack_free(stack);
+ sign_cb(FALSE, NULL, 0, context);
+ return NULL;
}
- silc_mp_init(&mp_tmp);
- silc_mp_init(&mp_dst);
+ silc_mp_sinit(stack, &mp_tmp);
+ silc_mp_sinit(stack, &mp_dst);
/* Data to MP */
silc_mp_bin2mp(padded, len, &mp_tmp);
silc_rsa_private_operation(key, &mp_tmp, &mp_dst);
/* MP to data */
- silc_mp_mp2bin_noalloc(&mp_dst, signature, len);
- *ret_signature_len = len;
+ silc_mp_mp2bin_noalloc(&mp_dst, padded, len);
+
+ /* Deliver result */
+ sign_cb(TRUE, padded, len, context);
memset(padded, 0, sizeof(padded));
- silc_mp_uninit(&mp_tmp);
- silc_mp_uninit(&mp_dst);
if (compute_hash)
memset(hashr, 0, sizeof(hashr));
+ silc_mp_suninit(stack, &mp_tmp);
+ silc_mp_suninit(stack, &mp_dst);
silc_asn1_free(asn1);
+ silc_stack_free(stack);
- return TRUE;
+ return NULL;
}
/* PKCS #1 verification with appendix. */
-SilcBool silc_pkcs1_verify(void *public_key,
- unsigned char *signature,
- SilcUInt32 signature_len,
- unsigned char *data,
- SilcUInt32 data_len,
- SilcHash hash)
+SilcAsyncOperation
+silc_pkcs1_verify(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key,
+ unsigned char *signature,
+ SilcUInt32 signature_len,
+ unsigned char *data,
+ SilcUInt32 data_len,
+ SilcHash hash,
+ SilcPKCSVerifyCb verify_cb,
+ void *context)
{
RsaPublicKey *key = public_key;
SilcBool ret = FALSE;
unsigned char *verify, unpadded[2048 + 1], hashr[SILC_HASH_MAXLEN];
SilcUInt32 verify_len, len = (key->bits + 7) / 8;
SilcBufferStruct di, ldi;
+ SilcBool has_null = TRUE;
SilcHash ihash = NULL;
- SilcAsn1 asn1 = NULL;
+ SilcStack stack;
+ SilcAsn1 asn1;
char *oid;
SILC_LOG_DEBUG(("Verify signature"));
- asn1 = silc_asn1_alloc(NULL);
- if (!asn1)
- return FALSE;
+ stack = silc_stack_alloc(2048, silc_crypto_stack());
- silc_mp_init(&mp_tmp2);
- silc_mp_init(&mp_dst);
+ asn1 = silc_asn1_alloc(stack);
+ if (!asn1) {
+ verify_cb(FALSE, context);
+ return NULL;
+ }
+
+ silc_mp_sinit(stack, &mp_tmp2);
+ silc_mp_sinit(stack, &mp_dst);
/* Format the signature into MP int */
silc_mp_bin2mp(signature, signature_len, &mp_tmp2);
/* If hash isn't given, allocate the one given in digest info */
if (!hash) {
+ has_null = FALSE;
+
/* Decode digest info */
if (!silc_asn1_decode(asn1, &di,
SILC_ASN1_OPTS(SILC_ASN1_ACCUMUL),
SILC_ASN1_SEQUENCE,
SILC_ASN1_SEQUENCE,
SILC_ASN1_OID(&oid),
+ SILC_ASN1_NULL_T(SILC_ASN1_OPTIONAL,
+ SILC_ASN1_TAG_NULL, &has_null),
SILC_ASN1_END,
SILC_ASN1_END, SILC_ASN1_END))
goto err;
SILC_ASN1_SEQUENCE,
SILC_ASN1_SEQUENCE,
SILC_ASN1_OID(oid),
- SILC_ASN1_NULL,
+ SILC_ASN1_NULL(has_null),
SILC_ASN1_END,
SILC_ASN1_OCTET_STRING(data, data_len),
SILC_ASN1_END, SILC_ASN1_END))
silc_buffer_len(&ldi)))
ret = TRUE;
+ /* Deliver result */
+ verify_cb(ret, context);
+
memset(verify, 0, verify_len);
memset(unpadded, 0, sizeof(unpadded));
silc_free(verify);
- silc_mp_uninit(&mp_tmp2);
- silc_mp_uninit(&mp_dst);
+ silc_mp_suninit(stack, &mp_tmp2);
+ silc_mp_suninit(stack, &mp_dst);
if (hash)
memset(hashr, 0, sizeof(hashr));
if (ihash)
silc_hash_free(ihash);
silc_asn1_free(asn1);
+ silc_stack_free(stack);
- return ret;
+ return NULL;
err:
memset(verify, 0, verify_len);
silc_free(verify);
- silc_mp_uninit(&mp_tmp2);
- silc_mp_uninit(&mp_dst);
+ silc_mp_suninit(stack, &mp_tmp2);
+ silc_mp_suninit(stack, &mp_dst);
if (ihash)
silc_hash_free(ihash);
silc_asn1_free(asn1);
- return FALSE;
+ silc_stack_free(stack);
+
+ verify_cb(FALSE, context);
+ return NULL;
}
/* PKCS #1 sign without hash oid */
-SilcBool silc_pkcs1_sign_no_oid(void *private_key,
- unsigned char *src,
- SilcUInt32 src_len,
- unsigned char *signature,
- SilcUInt32 signature_size,
- SilcUInt32 *ret_signature_len,
- SilcBool compute_hash,
- SilcHash hash)
+SilcAsyncOperation
+silc_pkcs1_sign_no_oid(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcBool compute_hash,
+ SilcHash hash,
+ SilcPKCSSignCb sign_cb,
+ void *context)
{
RsaPrivateKey *key = private_key;
SilcMPInt mp_tmp;
SilcMPInt mp_dst;
unsigned char padded[2048 + 1], hashr[SILC_HASH_MAXLEN];
SilcUInt32 len = (key->bits + 7) / 8;
+ SilcStack stack;
SILC_LOG_DEBUG(("Sign"));
- if (sizeof(padded) < len)
- return FALSE;
- if (signature_size < len)
- return FALSE;
+ if (sizeof(padded) < len) {
+ sign_cb(FALSE, NULL, 0, context);
+ return NULL;
+ }
/* Compute hash if requested */
if (compute_hash) {
/* Pad data */
if (!silc_pkcs1_encode(SILC_PKCS1_BT_PRV1, src, src_len,
- padded, len, NULL))
- return FALSE;
+ padded, len, NULL)) {
+ sign_cb(FALSE, NULL, 0, context);
+ return NULL;
+ }
+
+ stack = silc_stack_alloc(2048, silc_crypto_stack());
- silc_mp_init(&mp_tmp);
- silc_mp_init(&mp_dst);
+ silc_mp_sinit(stack, &mp_tmp);
+ silc_mp_sinit(stack, &mp_dst);
/* Data to MP */
silc_mp_bin2mp(padded, len, &mp_tmp);
silc_rsa_private_operation(key, &mp_tmp, &mp_dst);
/* MP to data */
- silc_mp_mp2bin_noalloc(&mp_dst, signature, len);
- *ret_signature_len = len;
+ silc_mp_mp2bin_noalloc(&mp_dst, padded, len);
+
+ /* Deliver result */
+ sign_cb(TRUE, padded, len, context);
memset(padded, 0, sizeof(padded));
- silc_mp_uninit(&mp_tmp);
- silc_mp_uninit(&mp_dst);
if (compute_hash)
memset(hashr, 0, sizeof(hashr));
+ silc_mp_suninit(stack, &mp_tmp);
+ silc_mp_suninit(stack, &mp_dst);
+ silc_stack_free(stack);
- return TRUE;
+ return NULL;
}
/* PKCS #1 verify without hash oid */
-SilcBool silc_pkcs1_verify_no_oid(void *public_key,
- unsigned char *signature,
- SilcUInt32 signature_len,
- unsigned char *data,
- SilcUInt32 data_len,
- SilcHash hash)
+SilcAsyncOperation
+silc_pkcs1_verify_no_oid(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key,
+ unsigned char *signature,
+ SilcUInt32 signature_len,
+ unsigned char *data,
+ SilcUInt32 data_len,
+ SilcHash hash,
+ SilcPKCSVerifyCb verify_cb,
+ void *context)
{
RsaPublicKey *key = public_key;
SilcBool ret = FALSE;
SilcMPInt mp_dst;
unsigned char *verify, unpadded[2048 + 1], hashr[SILC_HASH_MAXLEN];
SilcUInt32 verify_len, len = (key->bits + 7) / 8;
+ SilcStack stack;
SILC_LOG_DEBUG(("Verify signature"));
- silc_mp_init(&mp_tmp2);
- silc_mp_init(&mp_dst);
+ stack = silc_stack_alloc(2048, silc_crypto_stack());
+
+ silc_mp_sinit(stack, &mp_tmp2);
+ silc_mp_sinit(stack, &mp_dst);
/* Format the signature into MP int */
silc_mp_bin2mp(signature, signature_len, &mp_tmp2);
unpadded, sizeof(unpadded), &len)) {
memset(verify, 0, verify_len);
silc_free(verify);
- silc_mp_uninit(&mp_tmp2);
- silc_mp_uninit(&mp_dst);
- return FALSE;
+ silc_mp_suninit(stack, &mp_tmp2);
+ silc_mp_suninit(stack, &mp_dst);
+ silc_stack_free(stack);
+ verify_cb(FALSE, context);
+ return NULL;
}
/* Hash data if requested */
if (len == data_len && !memcmp(data, unpadded, len))
ret = TRUE;
+ /* Deliver result */
+ verify_cb(ret, context);
+
memset(verify, 0, verify_len);
memset(unpadded, 0, sizeof(unpadded));
- silc_free(verify);
- silc_mp_uninit(&mp_tmp2);
- silc_mp_uninit(&mp_dst);
if (hash)
memset(hashr, 0, sizeof(hashr));
+ silc_free(verify);
+ silc_mp_suninit(stack, &mp_tmp2);
+ silc_mp_suninit(stack, &mp_dst);
+ silc_stack_free(stack);
- return ret;
+ return NULL;
}
#ifndef SILCPKCS1_I_H
#define SILCPKCS1_I_H
-SilcBool silc_pkcs1_generate_key(SilcUInt32 keylen,
+SilcBool silc_pkcs1_generate_key(const struct SilcPKCSAlgorithmStruct *pkcs,
+ SilcUInt32 keylen,
SilcRng rng,
void **ret_public_key,
void **ret_private_key);
-int silc_pkcs1_import_public_key(unsigned char *key,
+int silc_pkcs1_import_public_key(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *key,
SilcUInt32 key_len,
void **ret_public_key);
-unsigned char *silc_pkcs1_export_public_key(void *public_key,
- SilcUInt32 *ret_len);
-SilcUInt32 silc_pkcs1_public_key_bitlen(void *public_key);
-void *silc_pkcs1_public_key_copy(void *public_key);
-SilcBool silc_pkcs1_public_key_compare(void *key1, void *key2);
-void silc_pkcs1_public_key_free(void *public_key);
-int silc_pkcs1_import_private_key(unsigned char *key,
+unsigned char *
+silc_pkcs1_export_public_key(const struct SilcPKCSAlgorithmStruct *pkcs,
+ SilcStack stack,
+ void *public_key,
+ SilcUInt32 *ret_len);
+SilcUInt32
+silc_pkcs1_public_key_bitlen(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key);
+void *silc_pkcs1_public_key_copy(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key);
+SilcBool
+silc_pkcs1_public_key_compare(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *key1, void *key2);
+void silc_pkcs1_public_key_free(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key);
+int silc_pkcs1_import_private_key(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *key,
SilcUInt32 key_len,
void **ret_private_key);
-unsigned char *silc_pkcs1_export_private_key(void *private_key,
- SilcUInt32 *ret_len);
-SilcUInt32 silc_pkcs1_private_key_bitlen(void *private_key);
-void silc_pkcs1_private_key_free(void *private_key);
-SilcBool silc_pkcs1_encrypt(void *public_key,
- unsigned char *src,
- SilcUInt32 src_len,
- unsigned char *dst,
- SilcUInt32 dst_size,
- SilcUInt32 *ret_dst_len,
- SilcRng rng);
-SilcBool silc_pkcs1_decrypt(void *private_key,
- unsigned char *src,
- SilcUInt32 src_len,
- unsigned char *dst,
- SilcUInt32 dst_size,
- SilcUInt32 *ret_dst_len);
-SilcBool silc_pkcs1_sign(void *private_key,
- unsigned char *src,
- SilcUInt32 src_len,
+unsigned char *
+silc_pkcs1_export_private_key(const struct SilcPKCSAlgorithmStruct *pkcs,
+ SilcStack stack,
+ void *private_key,
+ SilcUInt32 *ret_len);
+SilcUInt32
+silc_pkcs1_private_key_bitlen(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key);
+void silc_pkcs1_private_key_free(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key);
+SilcAsyncOperation
+silc_pkcs1_encrypt(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcRng rng,
+ SilcPKCSEncryptCb encrypt_cb,
+ void *context);
+SilcAsyncOperation
+silc_pkcs1_decrypt(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcPKCSDecryptCb decrypt_cb,
+ void *context);
+SilcAsyncOperation silc_pkcs1_sign(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcBool compute_hash,
+ SilcHash hash,
+ SilcPKCSSignCb sign_cb,
+ void *context);
+SilcAsyncOperation silc_pkcs1_verify(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key,
+ unsigned char *signature,
+ SilcUInt32 signature_len,
+ unsigned char *data,
+ SilcUInt32 data_len,
+ SilcHash hash,
+ SilcPKCSVerifyCb verify_cb,
+ void *context);
+SilcAsyncOperation
+silc_pkcs1_sign_no_oid(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcBool compute_hash,
+ SilcHash hash,
+ SilcPKCSSignCb sign_cb,
+ void *context);
+SilcAsyncOperation
+silc_pkcs1_verify_no_oid(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key,
unsigned char *signature,
- SilcUInt32 signature_size,
- SilcUInt32 *ret_signature_len,
- SilcBool compute_hash,
- SilcHash hash);
-SilcBool silc_pkcs1_verify(void *public_key,
- unsigned char *signature,
- SilcUInt32 signature_len,
- unsigned char *data,
- SilcUInt32 data_len,
- SilcHash hash);
-SilcBool silc_pkcs1_sign_no_oid(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 silc_pkcs1_verify_no_oid(void *public_key,
- unsigned char *signature,
- SilcUInt32 signature_len,
- unsigned char *data,
- SilcUInt32 data_len,
- SilcHash hash);
+ SilcUInt32 signature_len,
+ unsigned char *data,
+ SilcUInt32 data_len,
+ SilcHash hash,
+ SilcPKCSVerifyCb verify_cb,
+ void *context);
#endif /* SILCPKCS1_I_H */
--- /dev/null
+/*
+
+ silcpkcs_i.h
+
+ Author: Pekka Riikonen <priikone@silcnet.org>
+
+ Copyright (C) 1997 - 2007 Pekka Riikonen
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+*/
+
+#ifndef SILCPKCS_I_H
+#define SILCPKCS_I_H
+
+#ifndef SILCPKCS_H
+#error "Do not include this header directly"
+#endif
+
+/* The PKCS Algorithm object to represent any PKCS algorithm. This context
+ implements the PKCS algorithm, such as RSA, DSA, etc. */
+struct SilcPKCSAlgorithmStruct {
+ /* Algorithm name and scheme */
+ char *name; /* Eg. rsa, dsa, etc. */
+ char *scheme; /* Eg. pkcs1, openpgp, etc. */
+
+ /* 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)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ SilcUInt32 keylen,
+ SilcRng rng,
+ void **ret_public_key,
+ void **ret_private_key);
+
+ /* Public key routines. */
+
+ /* Import/create new public key. Returns the length of the data that was
+ imported from `key' or 0 on error. Returns the PKCS algorithm specific
+ public key to `ret_public_key'. */
+ int (*import_public_key)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *key, SilcUInt32 key_len,
+ void **ret_public_key);
+
+ /* Export/encode public key. Returns the encoded public key buffer that
+ the caller must free. */
+ unsigned char *
+ (*export_public_key)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ SilcStack stack,
+ void *public_key,
+ SilcUInt32 *ret_len);
+
+ /* Returns the bit length of public key */
+ SilcUInt32 (*public_key_bitlen)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key);
+
+ /* Duplicated public key */
+ void *(*public_key_copy)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key);
+
+ /* Compares two public keys. Returns TRUE if they are identical. */
+ SilcBool (*public_key_compare)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *key1, void *key2);
+
+ /* Free public key */
+ void (*public_key_free)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key);
+
+ /* Private key routines. */
+
+ /* Import/create new private key. Returns the length of the data that was
+ imported from `key' or 0 on error. Returns the PKCS algorithm specific
+ private key to `ret_private_key'. */
+ int (*import_private_key)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *key,
+ SilcUInt32 key_len,
+ void **ret_private_key);
+
+ /* Export/encode private key. Returns the encoded private key buffer that
+ the caller must free. */
+ unsigned char *
+ (*export_private_key)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ SilcStack stack,
+ void *private_key,
+ SilcUInt32 *ret_len);
+
+ /* Returns the bi length of private key */
+ SilcUInt32 (*private_key_bitlen)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key);
+
+ /* Free private key */
+ void (*private_key_free)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key);
+
+ /* Encrypt and decrypt operations */
+ SilcAsyncOperation (*encrypt)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcRng rng,
+ SilcPKCSEncryptCb encrypt_cb,
+ void *context);
+ SilcAsyncOperation (*decrypt)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcPKCSDecryptCb decrypt_cb,
+ void *context);
+
+ /* Signature and verification operations */
+ SilcAsyncOperation (*sign)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcBool compute_hash,
+ SilcHash hash,
+ SilcPKCSSignCb sign_cb,
+ void *context);
+ SilcAsyncOperation (*verify)(const struct SilcPKCSAlgorithmStruct *pkcs,
+ void *public_key,
+ unsigned char *signature,
+ SilcUInt32 signature_len,
+ unsigned char *data,
+ SilcUInt32 data_len,
+ SilcHash hash,
+ SilcPKCSVerifyCb verify_cb,
+ void *context);
+};
+
+/* The PKCS (Public Key Cryptosystem) object to represent any PKCS. This
+ context implements the PKCS, such as SILC public keys, X.509 certificates,
+ OpenPGP certificates, etc. under a common API. */
+struct SilcPKCSObjectStruct {
+ /* PKCS type */
+ SilcPKCSType type;
+
+ /* Public key routines */
+
+ /* Returns PKCS algorithm context from public key */
+ const SilcPKCSAlgorithm *
+ (*get_algorithm)(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key);
+
+ /* Imports from public key file */
+ SilcBool (*import_public_key_file)(const struct SilcPKCSObjectStruct *pkcs,
+ 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)(const struct SilcPKCSObjectStruct *pkcs,
+ void *key,
+ SilcUInt32 key_len,
+ void **ret_public_key);
+
+ /* Exports public key to file */
+ unsigned char *
+ (*export_public_key_file)(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ void *public_key,
+ SilcPKCSFileEncoding encoding,
+ SilcUInt32 *ret_len);
+
+ /* Export public key as binary data */
+ unsigned char *(*export_public_key)(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ void *public_key,
+ SilcUInt32 *ret_len);
+
+ /* Returns key length in bits */
+ SilcUInt32 (*public_key_bitlen)(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key);
+
+ /* Copy public key */
+ void *(*public_key_copy)(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key);
+
+ /* Compares public keys */
+ SilcBool (*public_key_compare)(const struct SilcPKCSObjectStruct *pkcs,
+ void *key1, void *key2);
+
+ /* Free public key */
+ void (*public_key_free)(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key);
+
+ /* Private key routines */
+
+ /* Imports from private key file */
+ SilcBool (*import_private_key_file)(const struct SilcPKCSObjectStruct *pkcs,
+ 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)(const struct SilcPKCSObjectStruct *pkcs,
+ void *key,
+ SilcUInt32 key_len,
+ void **ret_private_key);
+
+ /* Exports private key to file */
+ unsigned char *
+ (*export_private_key_file)(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ 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)(const struct SilcPKCSObjectStruct *pkcs,
+ SilcStack stack,
+ void *private_key,
+ SilcUInt32 *ret_len);
+
+ /* Returns key length in bits */
+ SilcUInt32 (*private_key_bitlen)(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key);
+
+ /* Free private key */
+ void (*private_key_free)(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key);
+
+ /* Encrypt and decrypt operations */
+ SilcAsyncOperation (*encrypt)(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcRng rng,
+ SilcPKCSEncryptCb encrypt_cb,
+ void *context);
+ SilcAsyncOperation (*decrypt)(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcPKCSDecryptCb decrypt_cb,
+ void *context);
+
+ /* Signature and verification operations */
+ SilcAsyncOperation (*sign)(const struct SilcPKCSObjectStruct *pkcs,
+ void *private_key,
+ unsigned char *src,
+ SilcUInt32 src_len,
+ SilcBool compute_hash,
+ SilcHash hash,
+ SilcPKCSSignCb sign_cb,
+ void *context);
+ SilcAsyncOperation (*verify)(const struct SilcPKCSObjectStruct *pkcs,
+ void *public_key,
+ unsigned char *signature,
+ SilcUInt32 signature_len,
+ unsigned char *data,
+ SilcUInt32 data_len,
+ SilcHash hash,
+ SilcPKCSVerifyCb verify_cb,
+ void *context);
+};
+
+#endif /* SILCPKCS_I_H */
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2003 Pekka Riikonen
+ Copyright (C) 1997 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
silc_rng_xor(rng, (r.ru_nvcsw ^ r.ru_nivcsw), pos++);
#endif /* SILC_SYMBIAN */
#endif /* HAVE_GETRUSAGE */
-
+
#ifdef SILC_RNG_DEBUG
SILC_LOG_HEXDUMP(("pool"), rng->pool, sizeof(rng->pool));
#endif
/* Returns non-zero random number binary data. */
-unsigned char *silc_rng_get_rn_data(SilcRng rng, SilcUInt32 len)
+SilcBool silc_rng_get_rn_data(SilcRng rng, SilcUInt32 len, unsigned char *buf,
+ SilcUInt32 buf_size)
{
int i;
- unsigned char *data;
- data = silc_calloc(len + 1, sizeof(*data));
+ if (len > buf_size)
+ return FALSE;
for (i = 0; i < len; i++)
- data[i] = silc_rng_get_byte(rng);
+ buf[i] = silc_rng_get_byte(rng);
- return data;
+ return TRUE;
}
/* Global RNG. This is global RNG that application can initialize so
return global_rng ? silc_rng_get_rn_string(global_rng, len) : NULL;
}
-unsigned char *silc_rng_global_get_rn_data(SilcUInt32 len)
+SilcBool silc_rng_global_get_rn_data(SilcRng rng, SilcUInt32 len,
+ unsigned char *buf, SilcUInt32 buf_size)
{
- return global_rng ? silc_rng_get_rn_data(global_rng, len) : NULL;
+ return global_rng ? silc_rng_get_rn_data(global_rng, len, buf,
+ buf_size) : FALSE;
}
void silc_rng_global_add_noise(unsigned char *buffer, SilcUInt32 len)
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2003 Pekka Riikonen
+ Copyright (C) 1997 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
*
* SYNOPSIS
*
- * unsigned char *silc_rng_get_rn_data(SilcRng rng, SilcUInt32 len);
+ * SilcBool silc_rng_get_rn_data(SilcRng rng, SilcUInt32 len,
+ * unsigned char *buf, SilcUInt32 buf_size);
*
* DESCRIPTION
*
- * Returns random binary data of the length of `len' bytes. The
- * caller must free returned data buffer. It is guaranteed the data
- * buffer does not include any zero (0x00) bytes.
+ * Returns random binary data of the length of `len' bytes to the `buf'
+ * of maximum size of `buf_size'. It is guaranteed the data buffer does
+ * not include any zero (0x00) bytes.
*
***/
-unsigned char *silc_rng_get_rn_data(SilcRng rng, SilcUInt32 len);
+SilcBool silc_rng_get_rn_data(SilcRng rng, SilcUInt32 len,
+ unsigned char *buf, SilcUInt32 buf_size);
/****f* silccrypt/SilcRNGAPI/silc_rng_add_noise
*
*
* SYNOPSIS
*
- * unsigned char *silc_rng_global_get_rn_data(SilcUInt32 len);
+ * SilcBool silc_rng_global_get_rn_data(SilcRng rng, SilcUInt32 len,
+ * unsigned char *buf,
+ * SilcUInt32 buf_size);
*
* DESCRIPTION
*
- * Returns random binary data of the length of `len' bytes. The
- * caller must free returned data buffer. It is guaranteed the data
- * buffer does not include any zero (0x00) bytes.
+ * Returns random binary data of the length of `len' bytes to the `buf'
+ * of maximum size of `buf_size'. It is guaranteed the data buffer does
+ * not include any zero (0x00) bytes.
*
***/
-unsigned char *silc_rng_global_get_rn_data(SilcUInt32 len);
+SilcBool silc_rng_global_get_rn_data(SilcRng rng, SilcUInt32 len,
+ unsigned char *buf, SilcUInt32 buf_size);
/****f* silccrypt/SilcRNGAPI/silc_rng_global_add_noise
*