Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2003 Pekka Riikonen
+ Copyright (C) 1997 - 2005 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
*/
/* $Id$ */
-#include "silcincludes.h"
+#include "silc.h"
#include "rsa.h"
/* Static list of PKCS for silc_pkcs_register_default(). */
const SilcPKCSObject silc_default_pkcs[] =
{
- /* RSA with PKCS #1 (Uses directly routines from Raw RSA operations) */
- { "rsa",
+ /* RSA with PKCS #1 for SILC PKCS */
+ { "rsa", SILC_PKCS_SILC,
silc_rsa_init, silc_rsa_clear_keys, silc_rsa_get_public_key,
silc_rsa_get_private_key, silc_rsa_set_public_key,
silc_rsa_set_private_key, silc_rsa_context_len,
silc_pkcs1_encrypt, silc_pkcs1_decrypt,
silc_pkcs1_sign, silc_pkcs1_verify },
- /* Raw RSA operations */
- { "rsa-raw",
+ /* RSASSA-PKCS1-V1_5 for SSH2 PKCS */
+/*
+ { "rsa", SILC_PKCS_SSH2,
silc_rsa_init, silc_rsa_clear_keys, silc_rsa_get_public_key,
silc_rsa_get_private_key, silc_rsa_set_public_key,
silc_rsa_set_private_key, silc_rsa_context_len,
- silc_rsa_encrypt, silc_rsa_decrypt,
- silc_rsa_sign, silc_rsa_verify },
+ silc_pkcs1_encrypt, silc_pkcs1_decrypt,
+ silc_pkcs1_sign, silc_pkcs1_verify },
+*/
- { NULL, NULL, NULL, NULL, NULL,
+ { NULL, 0, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL }
};
/* Register a new PKCS into SILC. This is used at the initialization of
the SILC. */
-bool silc_pkcs_register(const SilcPKCSObject *pkcs)
+SilcBool silc_pkcs_register(const SilcPKCSObject *pkcs)
{
#ifndef SILC_EPOC
SilcPKCSObject *new;
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))
+ if (!strcmp(entry->name, pkcs->name) &&
+ entry->type == pkcs->type)
return FALSE;
}
}
new = silc_calloc(1, sizeof(*new));
new->name = strdup(pkcs->name);
+ new->type = pkcs->type;
new->init = pkcs->init;
new->clear_keys = pkcs->clear_keys;
new->get_public_key = pkcs->get_public_key;
/* Unregister a PKCS from the SILC. */
-bool silc_pkcs_unregister(SilcPKCSObject *pkcs)
+SilcBool silc_pkcs_unregister(SilcPKCSObject *pkcs)
{
#ifndef SILC_EPOC
SilcPKCSObject *entry;
The application may use this to register the default PKCS if specific
PKCS in any specific order is not wanted. */
-bool silc_pkcs_register_default(void)
+SilcBool silc_pkcs_register_default(void)
{
#ifndef SILC_EPOC
int i;
return TRUE;
}
-bool silc_pkcs_unregister_all(void)
+SilcBool silc_pkcs_unregister_all(void)
{
#ifndef SILC_EPOC
SilcPKCSObject *entry;
/* Allocates a new SilcPKCS object. The new allocated object is returned
to the 'new_pkcs' argument. */
-bool silc_pkcs_alloc(const unsigned char *name, SilcPKCS *new_pkcs)
+SilcBool silc_pkcs_alloc(const unsigned char *name, SilcPKCSType type,
+ SilcPKCS *new_pkcs)
{
SilcPKCSObject *entry = NULL;
if (silc_pkcs_list) {
silc_dlist_start(silc_pkcs_list);
while ((entry = silc_dlist_get(silc_pkcs_list)) != SILC_LIST_END) {
- if (!strcmp(entry->name, name))
+ if (!strcmp(entry->name, name) && entry->type == type)
break;
}
}
/* On EPOC which don't have globals we check our constant hash list. */
int i;
for (i = 0; silc_default_pkcs[i].name; i++) {
- if (!strcmp(silc_default_pkcs[i].name, name)) {
+ if (!strcmp(silc_default_pkcs[i].name, name) &&
+ silc_default_pkcs[i].type == type) {
entry = (SilcPKCSObject *)&(silc_default_pkcs[i]);
break;
}
/* Return TRUE if PKCS algorithm `name' is supported. */
-bool silc_pkcs_is_supported(const unsigned char *name)
+SilcBool silc_pkcs_is_supported(const unsigned char *name)
{
#ifndef SILC_EPOC
SilcPKCSObject *entry;
/* Generate new key pair into the `pkcs' context. */
-bool silc_pkcs_generate_key(SilcPKCS pkcs, SilcUInt32 bits_key_len,
- SilcRng rng)
+SilcBool silc_pkcs_generate_key(SilcPKCS pkcs, SilcUInt32 bits_key_len,
+ SilcRng rng)
{
- bool ret = pkcs->pkcs->init(pkcs->context, bits_key_len, rng);
+ SilcBool ret = pkcs->pkcs->init(pkcs->context, bits_key_len, rng);
if (ret)
pkcs->key_len = bits_key_len;
return ret;
/* Encrypts */
-bool silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
+SilcBool silc_pkcs_encrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
unsigned char *dst, SilcUInt32 *dst_len)
{
return pkcs->pkcs->encrypt(pkcs->context, src, src_len, dst, dst_len);
/* Decrypts */
-bool silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
+SilcBool silc_pkcs_decrypt(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
unsigned char *dst, SilcUInt32 *dst_len)
{
return pkcs->pkcs->decrypt(pkcs->context, src, src_len, dst, dst_len);
/* Generates signature */
-bool silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
+SilcBool silc_pkcs_sign(SilcPKCS pkcs, unsigned char *src, SilcUInt32 src_len,
unsigned char *dst, SilcUInt32 *dst_len)
{
return pkcs->pkcs->sign(pkcs->context, src, src_len, dst, dst_len);
/* Verifies signature */
-bool silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature,
+SilcBool silc_pkcs_verify(SilcPKCS pkcs, unsigned char *signature,
SilcUInt32 signature_len, unsigned char *data,
SilcUInt32 data_len)
{
/* Generates signature with hash. The hash is signed. */
-bool silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
+SilcBool silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
unsigned char *src, SilcUInt32 src_len,
unsigned char *dst, SilcUInt32 *dst_len)
{
- unsigned char hashr[32];
+ unsigned char hashr[SILC_HASH_MAXLEN];
SilcUInt32 hash_len;
int ret;
/* Verifies signature with hash. The `data' is hashed and verified against
the `signature'. */
-bool silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash,
+SilcBool silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash,
unsigned char *signature,
SilcUInt32 signature_len,
unsigned char *data,
SilcUInt32 data_len)
{
- unsigned char hashr[32];
+ unsigned char hashr[SILC_HASH_MAXLEN];
SilcUInt32 hash_len;
int ret;
/* Decodes SILC style public key. Returns TRUE if the decoding was
successful. Allocates new public key as well. */
-bool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len,
+SilcBool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len,
SilcPublicKey *public_key)
{
SilcBufferStruct buf;
/* Get key data. We assume that rest of the buffer is key data. */
silc_buffer_pull(&buf, 2 + pkcs_len + 2 + identifier_len);
- key_len = buf.len;
+ key_len = silc_buffer_len(&buf);
ret = silc_buffer_unformat(&buf,
SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len),
SILC_STR_END);
code assumes that the PKCS routine checks the format of the key.
(check only if PKCS are registered) */
if (SILC_PKCS_LIST) {
- silc_pkcs_alloc(pkcs_name, &alg);
+ silc_pkcs_alloc(pkcs_name, SILC_PKCS_SILC, &alg);
if (!alg->pkcs->set_public_key(alg->context, key_data, key_len))
goto err;
silc_pkcs_free(alg);
/* Decode Public Key Payload and decodes the public key inside it to
to `payload'. */
-bool silc_pkcs_public_key_payload_decode(unsigned char *data,
+SilcBool silc_pkcs_public_key_payload_decode(unsigned char *data,
SilcUInt32 data_len,
SilcPublicKey *public_key)
{
/* Compares two public keys and returns TRUE if they are same key, and
FALSE if they are not same. */
-bool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2)
+SilcBool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2)
{
if (key1 == key2)
return TRUE;
/* Decodes SILC style private key. Returns TRUE if the decoding was
successful. Allocates new private key as well. */
-bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
+SilcBool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len,
SilcPrivateKey *private_key)
{
SilcBufferStruct buf;
goto err;
}
- if (pkcs_len < 1 || pkcs_len > buf.truelen) {
+ if (pkcs_len < 1 || pkcs_len > silc_buffer_truelen(&buf)) {
SILC_LOG_DEBUG(("Malformed private key buffer"));
goto err;
}
/* Get key data. We assume that rest of the buffer is key data. */
silc_buffer_pull(&buf, 2 + pkcs_len);
- key_len = buf.len;
+ key_len = silc_buffer_len(&buf);
ret = silc_buffer_unformat(&buf,
SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len),
SILC_STR_END);
code assumes that the PKCS routine checks the format of the key.
(check only if PKCS are registered) */
if (SILC_PKCS_LIST) {
- silc_pkcs_alloc(pkcs_name, &alg);
+ silc_pkcs_alloc(pkcs_name, SILC_PKCS_SILC, &alg);
if (!alg->pkcs->set_private_key(alg->context, key_data, key_len)) {
SILC_LOG_DEBUG(("Could not set private key data"));
goto err;
/* Internal routine to save public key */
-static bool silc_pkcs_save_public_key_internal(const char *filename,
+static SilcBool silc_pkcs_save_public_key_internal(const char *filename,
unsigned char *data,
SilcUInt32 data_len,
SilcUInt32 encoding)
SILC_STR_END);
/* Save into file */
- if (silc_file_writefile(filename, buf->data, buf->len)) {
+ if (silc_file_writefile(filename, buf->data, silc_buffer_len(buf))) {
silc_free(tmp);
silc_buffer_free(buf);
return FALSE;
/* Saves public key into file */
-bool silc_pkcs_save_public_key(const char *filename, SilcPublicKey public_key,
+SilcBool silc_pkcs_save_public_key(const char *filename, SilcPublicKey public_key,
SilcUInt32 encoding)
{
unsigned char *data;
SilcUInt32 data_len;
- bool ret;
+ SilcBool ret;
data = silc_pkcs_public_key_encode(public_key, &data_len);
ret = silc_pkcs_save_public_key_internal(filename, data, data_len,
/* Saves public key into file */
-bool silc_pkcs_save_public_key_data(const char *filename, unsigned char *data,
+SilcBool silc_pkcs_save_public_key_data(const char *filename, unsigned char *data,
SilcUInt32 data_len, SilcUInt32 encoding)
{
return silc_pkcs_save_public_key_internal(filename, data, data_len,
/* Internal routine to save private key. */
-static bool silc_pkcs_save_private_key_internal(const char *filename,
+static SilcBool silc_pkcs_save_private_key_internal(const char *filename,
unsigned char *data,
SilcUInt32 data_len,
unsigned char *key,
SILC_STR_END);
/* Encrypt. */
- silc_cipher_encrypt(aes, enc->data, enc->data, enc->len - len,
+ silc_cipher_encrypt(aes, enc->data, enc->data, silc_buffer_len(enc) - len,
silc_cipher_get_iv(aes));
silc_buffer_push(enc, 4);
/* Compute HMAC over the encrypted data and append the MAC to data.
The key is the first digest of the original key material. */
- data_len = enc->len - len;
+ data_len = silc_buffer_len(enc) - len;
silc_hmac_init_with_key(sha1hmac, keymat, 16);
silc_hmac_update(sha1hmac, enc->data, data_len);
silc_buffer_pull(enc, data_len);
silc_cipher_free(aes);
data = enc->data;
- data_len = enc->len;
+ data_len = silc_buffer_len(enc);
switch (encoding) {
case SILC_PKCS_FILE_BIN:
SILC_STR_END);
/* Save into a file */
- if (silc_file_writefile_mode(filename, buf->data, buf->len, 0600)) {
+ if (silc_file_writefile_mode(filename, buf->data,
+ silc_buffer_len(buf), 0600)) {
silc_buffer_clear(buf);
silc_buffer_free(buf);
silc_buffer_clear(enc);
/* Saves private key into file. */
-bool silc_pkcs_save_private_key(const char *filename,
+SilcBool silc_pkcs_save_private_key(const char *filename,
SilcPrivateKey private_key,
unsigned char *passphrase,
SilcUInt32 passphrase_len,
{
unsigned char *data;
SilcUInt32 data_len;
- bool ret;
+ SilcBool ret;
data = silc_pkcs_private_key_encode(private_key, &data_len);
ret = silc_pkcs_save_private_key_internal(filename, data, data_len,
/* Loads public key from file and allocates new public key. Returns TRUE
if loading was successful. */
-bool silc_pkcs_load_public_key(const char *filename, SilcPublicKey *public_key,
+SilcBool silc_pkcs_load_public_key(const char *filename, SilcPublicKey *public_key,
SilcUInt32 encoding)
{
unsigned char *cp, *old, *data, byte;
/* Load private key from file and allocates new private key. Returns TRUE
if loading was successful. */
-bool silc_pkcs_load_private_key(const char *filename,
+SilcBool silc_pkcs_load_private_key(const char *filename,
SilcPrivateKey *private_key,
unsigned char *passphrase,
SilcUInt32 passphrase_len,