Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2007 Pekka Riikonen
+ Copyright (C) 1997 - 2008 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
*/
-#include "silc.h"
+#include "silccrypto.h"
#include "silcpk_i.h"
/****************************** Key generation *******************************/
silc_free(privkey);
return FALSE;
}
- (*ret_public_key)->pkcs = pkcs;
+ (*ret_public_key)->pkcs = (SilcPKCSObject *)pkcs;
+ (*ret_public_key)->alg = alg;
(*ret_public_key)->public_key = pubkey;
/* Allocate private key */
silc_free(*ret_public_key);
return FALSE;
}
- (*ret_private_key)->pkcs = pkcs;
+ (*ret_private_key)->pkcs = (SilcPKCSObject *)pkcs;
+ (*ret_private_key)->alg = alg;
(*ret_private_key)->private_key = privkey;
/* Generate the algorithm key pair */
int len;
/* Protocol says that at least UN and HN must be provided as identifier */
- if (!strstr(identifier, "UN=") && !strstr(identifier, "HN=")) {
+ if (!strstr(identifier, "UN=") || !strstr(identifier, "HN=")) {
SILC_LOG_DEBUG(("The public does not have the required UN= and HN= "
"identifiers"));
return FALSE;
SilcBufferStruct buf;
char *identifier;
- if (!username || !host)
+ if (!username || !host) {
+ SILC_LOG_ERROR(("Public key identifier is missing UN and/or HN"));
return NULL;
- if (strlen(username) < 3 || strlen(host) < 3)
+ }
+ if (strlen(username) < 1 || strlen(host) < 1)
return NULL;
memset(&buf, 0, sizeof(buf));
if (version) {
if (strlen(version) > 1 || !isdigit(version[0])) {
silc_buffer_spurge(stack, &buf);
+ SILC_LOG_ERROR(("Public key identifier has invalid version (V)"));
return NULL;
}
silc_buffer_sformat(stack, &buf,
/* Returns PKCS algorithm context */
-const SilcPKCSAlgorithm *
-silc_pkcs_silc_get_algorithm(const struct SilcPKCSObjectStruct *pkcs,
- void *public_key)
+SILC_PKCS_GET_ALGORITHM(silc_pkcs_silc_get_algorithm)
{
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(const struct SilcPKCSObjectStruct *pkcs,
- unsigned char *filedata,
- SilcUInt32 filedata_len,
- SilcPKCSFileEncoding encoding,
- void **ret_public_key)
+SILC_PKCS_IMPORT_PUBLIC_KEY_FILE(silc_pkcs_silc_import_public_key_file)
{
SilcUInt32 i, len;
unsigned char *data = NULL;
/* Check start of file and remove header from the data. */
len = strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN);
if (filedata_len < len + strlen(SILC_PKCS_PUBLIC_KEYFILE_END)) {
- SILC_LOG_ERROR(("Malformed SILC public key header"));
+ SILC_LOG_DEBUG(("Malformed SILC public key header"));
return FALSE;
}
for (i = 0; i < len; i++) {
if (*filedata != SILC_PKCS_PUBLIC_KEYFILE_BEGIN[i]) {
- SILC_LOG_ERROR(("Malformed SILC public key header"));
+ SILC_LOG_DEBUG(("Malformed SILC public key header"));
return FALSE;
}
filedata++;
break;
}
- ret = silc_pkcs_silc_import_public_key(pkcs, filedata, filedata_len,
- ret_public_key);
+ ret = silc_pkcs_silc_import_public_key(pkcs, NULL, filedata, filedata_len,
+ ret_public_key, ret_alg);
silc_free(data);
return ret ? TRUE : FALSE;
/* Imports SILC protocol style public key */
-int silc_pkcs_silc_import_public_key(const struct SilcPKCSObjectStruct *pkcs,
- void *key,
- SilcUInt32 key_len,
- void **ret_public_key)
+SILC_PKCS_IMPORT_PUBLIC_KEY(silc_pkcs_silc_import_public_key)
{
- const SilcPKCSAlgorithm *alg;
SilcBufferStruct buf, alg_key;
SilcSILCPublicKey silc_pubkey = NULL;
SilcAsn1 asn1 = NULL;
silc_asn1_free(asn1);
*ret_public_key = silc_pubkey;
+ *ret_alg = alg;
return key_len;
/* Exports public key as SILC protocol style public key file */
-unsigned char *
-silc_pkcs_silc_export_public_key_file(const struct SilcPKCSObjectStruct *pkcs,
- SilcStack stack,
- void *public_key,
- SilcPKCSFileEncoding encoding,
- SilcUInt32 *ret_len)
+SILC_PKCS_EXPORT_PUBLIC_KEY_FILE(silc_pkcs_silc_export_public_key_file)
{
SilcBuffer buf;
unsigned char *key, *data;
/* Exports public key as SILC protocol style public key */
-unsigned char *
-silc_pkcs_silc_export_public_key(const struct SilcPKCSObjectStruct *pkcs,
- SilcStack stack,
- void *public_key,
- SilcUInt32 *ret_len)
+SILC_PKCS_EXPORT_PUBLIC_KEY(silc_pkcs_silc_export_public_key)
{
SilcSILCPublicKey silc_pubkey = public_key;
const SilcPKCSAlgorithm *alg = silc_pubkey->pkcs;
/* Return key length */
-SilcUInt32
-silc_pkcs_silc_public_key_bitlen(const struct SilcPKCSObjectStruct *pkcs,
- void *public_key)
+SILC_PKCS_PUBLIC_KEY_BITLEN(silc_pkcs_silc_public_key_bitlen)
{
SilcSILCPublicKey silc_pubkey = public_key;
return silc_pubkey->pkcs->public_key_bitlen(silc_pubkey->pkcs,
/* Copy public key */
-void *silc_pkcs_silc_public_key_copy(const struct SilcPKCSObjectStruct *pkcs,
- void *public_key)
+SILC_PKCS_PUBLIC_KEY_COPY(silc_pkcs_silc_public_key_copy)
{
SilcSILCPublicKey silc_pubkey = public_key, new_pubkey;
SilcPublicKeyIdentifier ident = &silc_pubkey->identifier;
/* Compares public keys */
-SilcBool
-silc_pkcs_silc_public_key_compare(const struct SilcPKCSObjectStruct *pkcs,
- void *key1, void *key2)
+SILC_PKCS_PUBLIC_KEY_COMPARE(silc_pkcs_silc_public_key_compare)
{
SilcSILCPublicKey k1 = key1, k2 = key2;
/* Frees public key */
-void silc_pkcs_silc_public_key_free(const struct SilcPKCSObjectStruct *pkcs,
- void *public_key)
+SILC_PKCS_PUBLIC_KEY_FREE(silc_pkcs_silc_public_key_free)
{
SilcSILCPublicKey silc_pubkey = public_key;
/* Imports SILC implementation style private key file */
-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)
+SILC_PKCS_IMPORT_PRIVATE_KEY_FILE(silc_pkcs_silc_import_private_key_file)
{
SilcCipher aes;
SilcHash sha1;
/* Check start of file and remove header from the data. */
len = strlen(SILC_PKCS_PRIVATE_KEYFILE_BEGIN);
if (filedata_len < len + strlen(SILC_PKCS_PRIVATE_KEYFILE_END)) {
- SILC_LOG_ERROR(("Malformed SILC private key header"));
+ SILC_LOG_DEBUG(("Malformed SILC private key header"));
return FALSE;
}
for (i = 0; i < len; i++) {
if (*filedata != SILC_PKCS_PRIVATE_KEYFILE_BEGIN[i]) {
- SILC_LOG_ERROR(("Malformed SILC private key header"));
+ SILC_LOG_DEBUG(("Malformed SILC private key header"));
return FALSE;
}
filedata++;
}
/* Allocate HMAC */
- if (!silc_hmac_alloc("hmac-sha1-96", NULL, &sha1hmac)) {
+ if (!silc_mac_alloc("hmac-sha1-96", &sha1hmac)) {
SILC_LOG_ERROR(("Could not allocate SHA1 HMAC, probably not registered"));
silc_hash_free(sha1);
silc_cipher_free(aes);
silc_cipher_set_key(aes, keymat, 256, FALSE);
/* First, verify the MAC of the private key data */
- mac_len = silc_hmac_len(sha1hmac);
- silc_hmac_init_with_key(sha1hmac, keymat, 16);
- silc_hmac_update(sha1hmac, filedata, len - mac_len);
- silc_hmac_final(sha1hmac, tmp, NULL);
+ mac_len = silc_mac_len(sha1hmac);
+ silc_mac_init_with_key(sha1hmac, keymat, 16);
+ silc_mac_update(sha1hmac, filedata, len - mac_len);
+ silc_mac_final(sha1hmac, tmp, NULL);
if (memcmp(tmp, filedata + (len - mac_len), mac_len)) {
SILC_LOG_DEBUG(("Integrity check for private key failed"));
memset(keymat, 0, sizeof(keymat));
memset(tmp, 0, sizeof(tmp));
- silc_hmac_free(sha1hmac);
+ silc_mac_free(sha1hmac);
silc_hash_free(sha1);
silc_cipher_free(aes);
return FALSE;
SILC_LOG_DEBUG(("Bad private key length in buffer!"));
memset(keymat, 0, sizeof(keymat));
memset(tmp, 0, sizeof(tmp));
- silc_hmac_free(sha1hmac);
+ silc_mac_free(sha1hmac);
silc_hash_free(sha1);
silc_cipher_free(aes);
return FALSE;
/* Cleanup */
memset(keymat, 0, sizeof(keymat));
memset(tmp, 0, sizeof(tmp));
- silc_hmac_free(sha1hmac);
+ silc_mac_free(sha1hmac);
silc_hash_free(sha1);
silc_cipher_free(aes);
/* Import the private key */
- ret = silc_pkcs_silc_import_private_key(pkcs, filedata, len, ret_private_key);
+ ret = silc_pkcs_silc_import_private_key(pkcs, NULL, NULL, 0, filedata,
+ len, ret_private_key, ret_alg);
silc_free(data);
/* Imports SILC implementation style private key */
-int silc_pkcs_silc_import_private_key(const struct SilcPKCSObjectStruct *pkcs,
- void *key,
- SilcUInt32 key_len,
- void **ret_private_key)
+SILC_PKCS_IMPORT_PRIVATE_KEY(silc_pkcs_silc_import_private_key)
{
SilcBufferStruct buf;
- const SilcPKCSAlgorithm *alg;
SilcBufferStruct alg_key;
SilcSILCPrivateKey silc_privkey = NULL;
SilcAsn1 asn1 = NULL;
silc_asn1_free(asn1);
*ret_private_key = silc_privkey;
+ *ret_alg = alg;
return key_len;
/* Exports private key as SILC implementation style private key file */
-unsigned char *
-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)
+SILC_PKCS_EXPORT_PRIVATE_KEY_FILE(silc_pkcs_silc_export_private_key_file)
{
SilcCipher aes;
SilcHash sha1;
}
/* Allocate HMAC */
- if (!silc_hmac_alloc("hmac-sha1-96", NULL, &sha1hmac)) {
+ if (!silc_mac_alloc("hmac-sha1-96", &sha1hmac)) {
SILC_LOG_ERROR(("Could not allocate SHA1 HMAC, probably not registered"));
silc_sfree(stack, key);
silc_hash_free(sha1);
block size of the cipher. */
/* Allocate buffer for encryption */
- len = silc_hmac_len(sha1hmac);
+ len = silc_mac_len(sha1hmac);
padlen = 16 + (16 - ((key_len + 4) % blocklen));
enc = silc_buffer_salloc_size(stack, 4 + 4 + key_len + padlen + len);
if (!enc) {
silc_sfree(stack, key);
- silc_hmac_free(sha1hmac);
+ silc_mac_free(sha1hmac);
silc_hash_free(sha1);
silc_cipher_free(aes);
return FALSE;
/* Compute HMAC over the encrypted data and append the MAC to data.
The key is the first digest of the original key material. */
key_len = silc_buffer_len(enc) - len;
- silc_hmac_init_with_key(sha1hmac, keymat, 16);
- silc_hmac_update(sha1hmac, enc->data, key_len);
+ silc_mac_init_with_key(sha1hmac, keymat, 16);
+ silc_mac_update(sha1hmac, enc->data, key_len);
silc_buffer_pull(enc, key_len);
- silc_hmac_final(sha1hmac, enc->data, NULL);
+ silc_mac_final(sha1hmac, enc->data, NULL);
silc_buffer_push(enc, key_len);
/* Cleanup */
memset(keymat, 0, sizeof(keymat));
memset(tmp, 0, sizeof(tmp));
- silc_hmac_free(sha1hmac);
+ silc_mac_free(sha1hmac);
silc_hash_free(sha1);
silc_cipher_free(aes);
/* Exports private key as SILC implementation style private key */
-unsigned char *
-silc_pkcs_silc_export_private_key(const struct SilcPKCSObjectStruct *pkcs,
- SilcStack stack,
- void *private_key,
- SilcUInt32 *ret_len)
+SILC_PKCS_EXPORT_PRIVATE_KEY(silc_pkcs_silc_export_private_key)
{
SilcSILCPrivateKey silc_privkey = private_key;
const SilcPKCSAlgorithm *alg = silc_privkey->pkcs;
/* Return key length */
-SilcUInt32
-silc_pkcs_silc_private_key_bitlen(const struct SilcPKCSObjectStruct *pkcs,
- void *private_key)
+SILC_PKCS_PRIVATE_KEY_BITLEN(silc_pkcs_silc_private_key_bitlen)
{
SilcSILCPrivateKey silc_privkey = private_key;
return silc_privkey->pkcs->private_key_bitlen(silc_privkey->pkcs,
/* Frees private key */
-void silc_pkcs_silc_private_key_free(const struct SilcPKCSObjectStruct *pkcs,
- void *private_key)
+SILC_PKCS_PRIVATE_KEY_FREE(silc_pkcs_silc_private_key_free)
{
SilcSILCPrivateKey silc_privkey = private_key;
/* Encrypts as specified in SILC protocol specification */
-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)
+SILC_PKCS_ENCRYPT(silc_pkcs_silc_encrypt)
{
SilcSILCPublicKey silc_pubkey = public_key;
/* Decrypts as specified in SILC protocol specification */
-SilcAsyncOperation
-silc_pkcs_silc_decrypt(const struct SilcPKCSObjectStruct *pkcs,
- void *private_key,
- unsigned char *src,
- SilcUInt32 src_len,
- SilcPKCSDecryptCb decrypt_cb,
- void *context)
+SILC_PKCS_DECRYPT(silc_pkcs_silc_decrypt)
{
SilcSILCPrivateKey silc_privkey = private_key;
/* Signs as specified in SILC protocol specification */
-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)
+SILC_PKCS_SIGN(silc_pkcs_silc_sign)
{
SilcSILCPrivateKey silc_privkey = private_key;
return silc_privkey->pkcs->sign(silc_privkey->pkcs,
silc_privkey->private_key,
src, src_len,
- compute_hash, hash,
+ compute_hash, hash, rng,
sign_cb, context);
}
/* Verifies as specified in SILC protocol specification */
-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)
+SILC_PKCS_VERIFY(silc_pkcs_silc_verify)
{
SilcSILCPublicKey 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 != NULL, hash, rng,
verify_cb, context);
}