/*
- silcpkcs.c
+ silcpkcs.c
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2001 Pekka Riikonen
+ Copyright (C) 1997 - 2002 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; either version 2 of the License, or
- (at your option) any later version.
-
+ 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
#include "rsa.h"
#include "pkcs1.h"
+/* The main SILC PKCS structure. */
+struct SilcPKCSStruct {
+ void *context; /* Algorithm internal context */
+ SilcPKCSObject *pkcs; /* Algorithm implementation */
+ SilcUInt32 key_len; /* Key length in bits */
+};
+
#ifndef SILC_EPOC
/* Dynamically registered list of PKCS. */
SilcDList silc_pkcs_list = NULL;
SILC_LOG_DEBUG(("Registering new PKCS `%s'", pkcs->name));
+ /* Check if exists already */
+ if (silc_pkcs_list) {
+ SilcPKCSObject *entry;
+ silc_dlist_start(silc_pkcs_list);
+ while ((entry = silc_dlist_get(silc_pkcs_list)) != SILC_LIST_END) {
+ if (!strcmp(entry->name, pkcs->name))
+ return FALSE;
+ }
+ }
+
new = silc_calloc(1, sizeof(*new));
new->name = strdup(pkcs->name);
new->init = pkcs->init;
while ((entry = silc_dlist_get(silc_pkcs_list)) != SILC_LIST_END) {
if (pkcs == SILC_ALL_PKCS || entry == pkcs) {
silc_dlist_del(silc_pkcs_list, entry);
+ silc_free(entry->name);
+ silc_free(entry);
if (silc_dlist_count(silc_pkcs_list) == 0) {
silc_dlist_uninit(silc_pkcs_list);
return TRUE;
}
+bool silc_pkcs_unregister_all(void)
+{
+#ifndef SILC_EPOC
+ SilcPKCSObject *entry;
+
+ if (!silc_pkcs_list)
+ return FALSE;
+
+ silc_dlist_start(silc_pkcs_list);
+ while ((entry = silc_dlist_get(silc_pkcs_list)) != SILC_LIST_END) {
+ silc_pkcs_unregister(entry);
+ if (!silc_pkcs_list)
+ break;
+ }
+#endif /* SILC_EPOC */
+ return TRUE;
+}
+
/* Allocates a new SilcPKCS object. The new allocated object is returned
to the 'new_pkcs' argument. */
*new_pkcs = silc_calloc(1, sizeof(**new_pkcs));
(*new_pkcs)->pkcs = entry;
(*new_pkcs)->context = silc_calloc(1, entry->context_len());
- (*new_pkcs)->get_key_len = silc_pkcs_get_key_len;
return TRUE;
}
return pkcs->key_len;
}
+const char *silc_pkcs_get_name(SilcPKCS pkcs)
+{
+ return pkcs->pkcs->name;
+}
+
/* Returns SILC style public key */
unsigned char *silc_pkcs_get_public_key(SilcPKCS pkcs, SilcUInt32 *len)
/* Sets private key from SilcPrivateKey. */
-int silc_pkcs_private_key_set(SilcPKCS pkcs, SilcPrivateKey private_key)
+SilcUInt32 silc_pkcs_private_key_set(SilcPKCS pkcs, SilcPrivateKey private_key)
{
- return pkcs->pkcs->set_private_key(pkcs->context, private_key->prv,
- private_key->prv_len);
+ SilcUInt32 key_len;
+ key_len = pkcs->pkcs->set_private_key(pkcs->context, private_key->prv,
+ private_key->prv_len);
+ if (!pkcs->key_len)
+ pkcs->key_len = key_len;
+ return pkcs->key_len;
}
/* Sets private key from data. */
-int silc_pkcs_private_key_data_set(SilcPKCS pkcs, unsigned char *prv,
- SilcUInt32 prv_len)
+SilcUInt32 silc_pkcs_private_key_data_set(SilcPKCS pkcs, unsigned char *prv,
+ SilcUInt32 prv_len)
{
- return pkcs->pkcs->set_private_key(pkcs->context, prv, prv_len);
+ SilcUInt32 key_len;
+ key_len = pkcs->pkcs->set_private_key(pkcs->context, prv, prv_len);
+ if (!pkcs->key_len)
+ pkcs->key_len = key_len;
+ return pkcs->key_len;
}
/* Encrypts */
int ret;
silc_hash_make(hash, src, src_len, hashr);
- hash_len = hash->hash->hash_len;
+ hash_len = silc_hash_len(hash);
SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len);
int ret;
silc_hash_make(hash, data, data_len, hashr);
- hash_len = hash->hash->hash_len;
+ hash_len = silc_hash_len(hash);
SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len);
/* Allocates SILC style public key formed from sent arguments. All data
is duplicated. */
-SilcPublicKey silc_pkcs_public_key_alloc(char *name, char *identifier,
- unsigned char *pk,
+SilcPublicKey silc_pkcs_public_key_alloc(const char *name,
+ const char *identifier,
+ const unsigned char *pk,
SilcUInt32 pk_len)
{
SilcPublicKey public_key;
+ char *tmp = NULL;
public_key = silc_calloc(1, sizeof(*public_key));
- public_key->len = 4 + 2 + strlen(name) + 2 + strlen(identifier) + pk_len;
public_key->name = strdup(name);
- public_key->identifier = strdup(identifier);
public_key->pk_len = pk_len;
public_key->pk = silc_calloc(pk_len, sizeof(*public_key->pk));
memcpy(public_key->pk, pk, pk_len);
+ if (!silc_utf8_valid(identifier, strlen(identifier))) {
+ int len = silc_utf8_encoded_len(identifier, strlen(identifier), 0);
+ tmp = silc_calloc(len + 1, sizeof(*tmp));
+ silc_utf8_encode(identifier, strlen(identifier), 0, tmp, len);
+ identifier = tmp;
+ }
+
+ public_key->identifier = strdup(identifier);
+ public_key->len = 4 + 2 + strlen(name) + 2 + strlen(identifier) + pk_len;
+ silc_free(tmp);
+
return public_key;
}
/* Allocates SILC private key formed from sent arguments. All data is
duplicated. */
-SilcPrivateKey silc_pkcs_private_key_alloc(char *name, unsigned char *prv,
+SilcPrivateKey silc_pkcs_private_key_alloc(const char *name,
+ const unsigned char *prv,
SilcUInt32 prv_len)
{
SilcPrivateKey private_key;
return FALSE;
}
+/* Copies the public key indicated by `public_key' and returns new allocated
+ public key which is indentical to the `public_key'. */
+
+SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key)
+{
+ SilcPublicKey key = silc_calloc(1, sizeof(*key));
+ if (!key)
+ return NULL;
+
+ key->len = public_key->len;
+ key->name = silc_memdup(public_key->name, strlen(public_key->name));
+ key->identifier = silc_memdup(public_key->identifier,
+ strlen(public_key->identifier));
+ key->pk = silc_memdup(public_key->pk, public_key->pk_len);
+ key->pk_len = public_key->pk_len;
+
+ return key;
+}
+
/* Encodes SILC private key from SilcPrivateKey. Returns the encoded data. */
unsigned char *
case SILC_PKCS_FILE_BIN:
break;
case SILC_PKCS_FILE_PEM:
- data = silc_encode_pem_file(data, data_len);
+ data = silc_pem_encode_file(data, data_len);
data_len = strlen(data);
break;
}
case SILC_PKCS_FILE_BIN:
break;
case SILC_PKCS_FILE_PEM:
- data = silc_encode_pem_file(data, data_len);
+ data = silc_pem_encode_file(data, data_len);
data_len = strlen(data);
break;
}
case SILC_PKCS_FILE_BIN:
break;
case SILC_PKCS_FILE_PEM:
- data = silc_decode_pem(data, len, &len);
+ data = silc_pem_decode(data, len, &len);
memset(old, 0, data_len);
silc_free(old);
old = data;
case SILC_PKCS_FILE_BIN:
break;
case SILC_PKCS_FILE_PEM:
- data = silc_decode_pem(data, len, &len);
+ data = silc_pem_decode(data, len, &len);
break;
}