X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Fsilcpk.c;h=e4a000788c79f71fdae9da4e7516470d498d612f;hb=e9374395ec9747bddd3ea0bfd3e5a17717e97b31;hp=7e7c234e72681cd6355c0e6b69aec9e51cf37215;hpb=35cdce343e56b7bae588a4fe7ba0bf8615a48170;p=silc.git diff --git a/lib/silccrypt/silcpk.c b/lib/silccrypt/silcpk.c index 7e7c234e..e4a00078 100644 --- a/lib/silccrypt/silcpk.c +++ b/lib/silccrypt/silcpk.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2006 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 @@ -25,7 +25,6 @@ /* Generate new SILC key pair. */ SilcBool silc_pkcs_silc_generate_key(const char *algorithm, - const char *scheme, SilcUInt32 bits_key_len, const char *identifier, SilcRng rng, @@ -36,6 +35,7 @@ SilcBool silc_pkcs_silc_generate_key(const char *algorithm, SilcSILCPrivateKey privkey; const SilcPKCSAlgorithm *alg; const SilcPKCSObject *pkcs; + SilcUInt32 version; SILC_LOG_DEBUG(("Generating SILC %s key pair with key length %d bits", algorithm, bits_key_len)); @@ -47,21 +47,28 @@ SilcBool silc_pkcs_silc_generate_key(const char *algorithm, if (!pkcs) return FALSE; - alg = silc_pkcs_find_algorithm(algorithm, scheme); - if (!alg) - return FALSE; - /* Allocate SILC public key */ pubkey = silc_calloc(1, sizeof(*pubkey)); if (!pubkey) return FALSE; - pubkey->pkcs = alg; /* Decode identifier */ - if (!silc_pkcs_silc_decode_identifier(identifier, &pubkey->identifier)) { + if (!silc_pkcs_silc_decode_identifier(identifier, &pubkey->identifier)) + return FALSE; + + if (pubkey->identifier.version && atoi(pubkey->identifier.version) >= 2) + version = 2; + else + version = 1; + + /* Allocate algorithm */ + alg = silc_pkcs_find_algorithm(algorithm, (version == 1 ? "pkcs1-no-oid" : + "pkcs1")); + if (!alg) { silc_free(pubkey); return FALSE; } + pubkey->pkcs = alg; /* Allocate SILC private key */ privkey = silc_calloc(1, sizeof(*privkey)); @@ -117,7 +124,7 @@ SilcBool silc_pkcs_silc_decode_identifier(const char *identifier, 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; @@ -169,6 +176,8 @@ SilcBool silc_pkcs_silc_decode_identifier(const char *identifier, ident->org = strdup(item + strcspn(cp, "=") + 1); else if (strstr(item, "C=")) ident->country = strdup(item + strcspn(cp, "=") + 1); + else if (strstr(item, "V=")) + ident->version = strdup(item + strcspn(cp, "=") + 1); cp += len; if (strlen(cp) < 1) @@ -189,100 +198,102 @@ SilcBool silc_pkcs_silc_decode_identifier(const char *identifier, char *silc_pkcs_silc_encode_identifier(char *username, char *host, char *realname, char *email, - char *org, char *country) + char *org, char *country, + char *version) { - SilcBuffer buf; + SilcBufferStruct buf; char *identifier; - SilcUInt32 len, tlen = 0; if (!username || !host) return NULL; - - len = (username ? strlen(username) : 0) + - (host ? strlen(host) : 0) + - (realname ? strlen(realname) : 0) + - (email ? strlen(email) : 0) + - (org ? strlen(org) : 0) + - (country ? strlen(country) : 0); - - if (len < 3) + if (strlen(username) < 1 || strlen(host) < 1) return NULL; - len += 3 + 5 + 5 + 4 + 4 + 4; - buf = silc_buffer_alloc(len); - if (!buf) - return NULL; - silc_buffer_pull_tail(buf, len); + memset(&buf, 0, sizeof(buf)); - if (username) { - silc_buffer_format(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_pull(buf, 3 + strlen(username)); - tlen = 3 + strlen(username); - } - if (host) { - silc_buffer_format(buf, + 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_pull(buf, 5 + strlen(host)); - tlen += 5 + strlen(host); - } - if (realname) { - silc_buffer_format(buf, + 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_pull(buf, 5 + strlen(realname)); - tlen += 5 + strlen(realname); - } - if (email) { - silc_buffer_format(buf, + 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_pull(buf, 4 + strlen(email)); - tlen += 4 + strlen(email); - } - if (org) { - silc_buffer_format(buf, + 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_pull(buf, 4 + strlen(org)); - tlen += 4 + strlen(org); - } - if (country) { - silc_buffer_format(buf, + 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_pull(buf, 4 + strlen(country)); - tlen += 4 + strlen(country); + + if (version) { + if (strlen(version) > 1 || !isdigit(version[0])) { + silc_buffer_purge(&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_push(buf, buf->data - buf->head); - identifier = silc_calloc(tlen + 1, sizeof(*identifier)); - if (!identifier) - return NULL; - memcpy(identifier, buf->data, tlen); - silc_buffer_free(buf); + silc_buffer_format(&buf, SILC_STR_UI_CHAR(0), SILC_STR_END); + identifier = silc_buffer_steal(&buf, NULL); return identifier; } +/* Return SILC public key version */ + +int silc_pkcs_silc_public_key_version(SilcPublicKey public_key) +{ + SilcSILCPublicKey silc_pubkey; + + if (silc_pkcs_get_type(public_key) != SILC_PKCS_SILC) + return -1; + + silc_pubkey = public_key->public_key; + + /* If version identifire is not present it is version 1. */ + if (!silc_pubkey->identifier.version) + return 1; + + return atoi(silc_pubkey->identifier.version); +} /*************************** Public key routines *****************************/ @@ -303,7 +314,7 @@ SilcBool silc_pkcs_silc_import_public_key_file(unsigned char *filedata, { SilcUInt32 i, len; unsigned char *data = NULL; - SilcBool ret; + int ret; SILC_LOG_DEBUG(("Parsing SILC public key file")); @@ -312,11 +323,15 @@ SilcBool silc_pkcs_silc_import_public_key_file(unsigned char *filedata, /* 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)) + if (filedata_len < len + strlen(SILC_PKCS_PUBLIC_KEYFILE_END)) { + SILC_LOG_ERROR(("Malformed SILC public key header")); return FALSE; + } for (i = 0; i < len; i++) { - if (*filedata != SILC_PKCS_PUBLIC_KEYFILE_BEGIN[i]) + if (*filedata != SILC_PKCS_PUBLIC_KEYFILE_BEGIN[i]) { + SILC_LOG_ERROR(("Malformed SILC public key header")); return FALSE; + } filedata++; } filedata_len -= (strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN) + @@ -327,7 +342,7 @@ SilcBool silc_pkcs_silc_import_public_key_file(unsigned char *filedata, break; case SILC_PKCS_FILE_BASE64: - data = silc_pem_decode(filedata, filedata_len, &filedata_len); + data = silc_base64_decode(filedata, filedata_len, &filedata_len); if (!data) return FALSE; filedata = data; @@ -338,14 +353,14 @@ SilcBool silc_pkcs_silc_import_public_key_file(unsigned char *filedata, ret_public_key); silc_free(data); - return ret; + return ret ? TRUE : FALSE; } /* Imports SILC protocol style public key */ -SilcBool silc_pkcs_silc_import_public_key(unsigned char *key, - SilcUInt32 key_len, - void **ret_public_key) +int silc_pkcs_silc_import_public_key(unsigned char *key, + SilcUInt32 key_len, + void **ret_public_key) { const SilcPKCSAlgorithm *pkcs; SilcBufferStruct buf, alg_key; @@ -359,12 +374,13 @@ SilcBool silc_pkcs_silc_import_public_key(unsigned char *key, SILC_LOG_DEBUG(("Parsing SILC public key")); if (!ret_public_key) - return FALSE; + return 0; silc_buffer_set(&buf, key, key_len); /* Get length */ ret = silc_buffer_unformat(&buf, + SILC_STR_ADVANCE, SILC_STR_UI_INT(&totlen), SILC_STR_END); if (ret == -1) @@ -380,7 +396,7 @@ SilcBool silc_pkcs_silc_import_public_key(unsigned char *key, /* Get algorithm name and identifier */ ret = silc_buffer_unformat(&buf, - SILC_STR_OFFSET(4), + SILC_STR_ADVANCE, SILC_STR_UI16_NSTRING_ALLOC(&pkcs_name, &pkcs_len), SILC_STR_UI16_NSTRING_ALLOC(&ident, &identifier_len), SILC_STR_END); @@ -392,11 +408,9 @@ SilcBool silc_pkcs_silc_import_public_key(unsigned char *key, goto err; /* Get key data */ - silc_buffer_pull(&buf, 4 + 2 + pkcs_len + 2 + identifier_len); keydata_len = silc_buffer_len(&buf); ret = silc_buffer_unformat(&buf, - SILC_STR_UI_XNSTRING(&key_data, - keydata_len), + SILC_STR_DATA(&key_data, keydata_len), SILC_STR_END); if (ret == -1) goto err; @@ -414,15 +428,27 @@ SilcBool silc_pkcs_silc_import_public_key(unsigned char *key, if (!asn1) goto err; + SILC_LOG_DEBUG(("Public key version %s", + (!silc_pubkey->identifier.version ? "1" : + silc_pubkey->identifier.version))); + if (!strcmp(pkcs_name, "rsa")) { /* Parse the SILC RSA public key */ SilcUInt32 e_len, n_len; SilcMPInt n, e; - /* Get PKCS object */ - pkcs = silc_pkcs_find_algorithm(pkcs_name, "pkcs1-no-oid"); + /* Get PKCS object. Different PKCS #1 scheme is used with different + versions. */ + if (!silc_pubkey->identifier.version || + atoi(silc_pubkey->identifier.version) <= 1) { + /* Version 1 */ + pkcs = silc_pkcs_find_algorithm(pkcs_name, "pkcs1-no-oid"); + } else { + /* Version 2 and newer */ + pkcs = silc_pkcs_find_algorithm(pkcs_name, "pkcs1"); + } if (!pkcs) { - SILC_LOG_DEBUG(("Unsupported PKCS algorithm")); + SILC_LOG_DEBUG(("Unsupported PKCS algorithm: rsa")); goto err; } silc_pubkey->pkcs = pkcs; @@ -471,10 +497,9 @@ SilcBool silc_pkcs_silc_import_public_key(unsigned char *key, } /* Import PKCS algorithm public key */ - if (pkcs->import_public_key) - if (!pkcs->import_public_key(alg_key.data, silc_buffer_len(&alg_key), - &silc_pubkey->public_key)) - goto err; + if (!pkcs->import_public_key(alg_key.data, silc_buffer_len(&alg_key), + &silc_pubkey->public_key)) + goto err; silc_free(pkcs_name); silc_free(ident); @@ -482,7 +507,7 @@ SilcBool silc_pkcs_silc_import_public_key(unsigned char *key, *ret_public_key = silc_pubkey; - return TRUE; + return key_len; err: silc_free(pkcs_name); @@ -490,7 +515,7 @@ SilcBool silc_pkcs_silc_import_public_key(unsigned char *key, silc_free(silc_pubkey); if (asn1) silc_asn1_free(asn1); - return FALSE; + return 0; } /* Exports public key as SILC protocol style public key file */ @@ -516,7 +541,7 @@ silc_pkcs_silc_export_public_key_file(void *public_key, break; case SILC_PKCS_FILE_BASE64: - data = silc_pem_encode_file(key, key_len); + data = silc_base64_encode_file(key, key_len); if (!data) return NULL; silc_free(key); @@ -570,8 +595,10 @@ unsigned char *silc_pkcs_silc_export_public_key(void *public_key, /* Export PKCS algorithm public key */ if (pkcs->export_public_key) pk = pkcs->export_public_key(silc_pubkey->public_key, &pk_len); - if (!pk) + if (!pk) { + SILC_LOG_ERROR(("Error exporting PKCS algorithm key")); return NULL; + } silc_buffer_set(&alg_key, pk, pk_len); /* Encode identifier */ @@ -581,9 +608,12 @@ unsigned char *silc_pkcs_silc_export_public_key(void *public_key, silc_pubkey->identifier.realname, silc_pubkey->identifier.email, silc_pubkey->identifier.org, - silc_pubkey->identifier.country); - if (!identifier) + silc_pubkey->identifier.country, + silc_pubkey->identifier.version); + if (!identifier) { + SILC_LOG_ERROR(("Error encoding SILC public key identifier")); goto err; + } asn1 = silc_asn1_alloc(); if (!asn1) @@ -632,7 +662,7 @@ unsigned char *silc_pkcs_silc_export_public_key(void *public_key, goto err; } else { - SILC_LOG_DEBUG(("Unsupported PKCS algorithm")); + SILC_LOG_ERROR(("Unsupported PKCS algorithm: %s", pkcs->name)); goto err; } @@ -655,6 +685,7 @@ unsigned char *silc_pkcs_silc_export_public_key(void *public_key, silc_buffer_free(buf); silc_free(key); silc_free(identifier); + silc_buffer_purge(&alg_key); silc_asn1_free(asn1); return ret; @@ -683,6 +714,7 @@ SilcUInt32 silc_pkcs_silc_public_key_bitlen(void *public_key) void *silc_pkcs_silc_public_key_copy(void *public_key) { SilcSILCPublicKey silc_pubkey = public_key, new_pubkey; + SilcPublicKeyIdentifier ident = &silc_pubkey->identifier; new_pubkey = silc_calloc(1, sizeof(*new_pubkey)); if (!new_pubkey) @@ -696,6 +728,28 @@ void *silc_pkcs_silc_public_key_copy(void *public_key) return NULL; } + if (ident->username) + new_pubkey->identifier.username = + silc_memdup(ident->username, strlen(ident->username)); + if (ident->host) + new_pubkey->identifier.host = + silc_memdup(ident->host, strlen(ident->host)); + if (ident->realname) + new_pubkey->identifier.realname = + silc_memdup(ident->realname, strlen(ident->realname)); + if (ident->email) + new_pubkey->identifier.email = + silc_memdup(ident->email, strlen(ident->email)); + if (ident->org) + new_pubkey->identifier.org = + silc_memdup(ident->org, strlen(ident->org)); + if (ident->country) + new_pubkey->identifier.country = + silc_memdup(ident->country, strlen(ident->country)); + if (ident->version) + new_pubkey->identifier.version = + silc_memdup(ident->version, strlen(ident->version)); + return new_pubkey; } @@ -744,6 +798,12 @@ SilcBool silc_pkcs_silc_public_key_compare(void *key1, void *key2) strcmp(k1->identifier.country, k2->identifier.country))) return FALSE; + if ((k1->identifier.version && !k2->identifier.version) || + (!k1->identifier.version && k2->identifier.version) || + (k1->identifier.version && k2->identifier.version && + strcmp(k1->identifier.version, k2->identifier.version))) + return FALSE; + return k1->pkcs->public_key_compare(k1->public_key, k2->public_key); } @@ -761,6 +821,7 @@ void silc_pkcs_silc_public_key_free(void *public_key) silc_free(silc_pubkey->identifier.email); silc_free(silc_pubkey->identifier.org); silc_free(silc_pubkey->identifier.country); + silc_free(silc_pubkey->identifier.version); silc_free(silc_pubkey); } @@ -785,17 +846,21 @@ SilcBool silc_pkcs_silc_import_private_key_file(unsigned char *filedata, SilcUInt32 blocklen; unsigned char tmp[32], keymat[64], *data = NULL; SilcUInt32 i, len, magic, mac_len; - SilcBool ret; + int ret; SILC_LOG_DEBUG(("Parsing SILC private key file")); /* 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)) + if (filedata_len < len + strlen(SILC_PKCS_PRIVATE_KEYFILE_END)) { + SILC_LOG_ERROR(("Malformed SILC private key header")); return FALSE; + } for (i = 0; i < len; i++) { - if (*filedata != SILC_PKCS_PRIVATE_KEYFILE_BEGIN[i]) + if (*filedata != SILC_PKCS_PRIVATE_KEYFILE_BEGIN[i]) { + SILC_LOG_ERROR(("Malformed SILC private key header")); return FALSE; + } filedata++; } @@ -807,7 +872,7 @@ SilcBool silc_pkcs_silc_import_private_key_file(unsigned char *filedata, break; case SILC_PKCS_FILE_BASE64: - data = silc_pem_decode(filedata, filedata_len, &len); + data = silc_base64_decode(filedata, filedata_len, &len); if (!data) return FALSE; filedata = data; @@ -909,17 +974,18 @@ SilcBool silc_pkcs_silc_import_private_key_file(unsigned char *filedata, silc_free(data); - return ret; + return ret ? TRUE : FALSE; } /* Private key version */ #define SILC_PRIVATE_KEY_VERSION_1 0x82171273 +#define SILC_PRIVATE_KEY_VERSION_2 0xf911a3d1 /* Imports SILC implementation style private key */ -SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, - SilcUInt32 key_len, - void **ret_private_key) +int silc_pkcs_silc_import_private_key(unsigned char *key, + SilcUInt32 key_len, + void **ret_private_key) { SilcBufferStruct buf; const SilcPKCSAlgorithm *pkcs; @@ -934,7 +1000,7 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, SILC_LOG_DEBUG(("Parsing SILC private key")); if (!ret_private_key) - return FALSE; + return 0; silc_buffer_set(&buf, key, key_len); @@ -978,17 +1044,8 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, unsigned char *tmp; SilcUInt32 len, ver; - /* Get PKCS object */ - pkcs = silc_pkcs_find_algorithm(pkcs_name, "pkcs1-no-oid"); - if (!pkcs) { - SILC_LOG_DEBUG(("Unsupported PKCS algorithm")); - goto err; - } - silc_privkey->pkcs = pkcs; - if (keydata_len < 4) goto err; - silc_buffer_set(&k, key_data, keydata_len); /* Get version. Key without the version is old style private key @@ -999,8 +1056,10 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, goto err; silc_buffer_pull(&k, 4); - if (ver != SILC_PRIVATE_KEY_VERSION_1) { + if (ver != SILC_PRIVATE_KEY_VERSION_1 && + ver != SILC_PRIVATE_KEY_VERSION_2) { len = ver; + ver = 0; } else { if (silc_buffer_unformat(&k, SILC_STR_UI_INT(&len), @@ -1009,9 +1068,28 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, silc_buffer_pull(&k, 4); } + /* Get PKCS object. Different PKCS #1 scheme is used with different + versions. */ + if (ver == 0 || ver == SILC_PRIVATE_KEY_VERSION_1) { + /* Version 0 and 1 */ + pkcs = silc_pkcs_find_algorithm(pkcs_name, "pkcs1-no-oid"); + } else { + /* Version 2 and newer */ + pkcs = silc_pkcs_find_algorithm(pkcs_name, "pkcs1"); + } + if (!pkcs) { + SILC_LOG_DEBUG(("Unsupported PKCS algorithm")); + goto err; + } + silc_privkey->pkcs = pkcs; + + SILC_LOG_DEBUG(("Private key version %s", + (ver == SILC_PRIVATE_KEY_VERSION_1 ? "1" : + ver == SILC_PRIVATE_KEY_VERSION_2 ? "2" : "0"))); + /* Get e */ if (silc_buffer_unformat(&k, - SILC_STR_UI_XNSTRING(&tmp, len), + SILC_STR_DATA(&tmp, len), SILC_STR_END) < 0) goto err; silc_mp_init(&e); @@ -1025,7 +1103,7 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, goto err; silc_buffer_pull(&k, 4); if (silc_buffer_unformat(&k, - SILC_STR_UI_XNSTRING(&tmp, len), + SILC_STR_DATA(&tmp, len), SILC_STR_END) < 0) goto err; silc_mp_init(&n); @@ -1039,7 +1117,7 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, goto err; silc_buffer_pull(&k, 4); if (silc_buffer_unformat(&k, - SILC_STR_UI_XNSTRING(&tmp, len), + SILC_STR_DATA(&tmp, len), SILC_STR_END) < 0) goto err; silc_mp_init(&d); @@ -1053,7 +1131,7 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, goto err; silc_buffer_pull(&k, 4); if (silc_buffer_unformat(&k, - SILC_STR_UI_XNSTRING(&tmp, len), + SILC_STR_DATA(&tmp, len), SILC_STR_END) < 0) goto err; silc_mp_init(&dp); @@ -1067,14 +1145,14 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, goto err; silc_buffer_pull(&k, 4); if (silc_buffer_unformat(&k, - SILC_STR_UI_XNSTRING(&tmp, len), + SILC_STR_DATA(&tmp, len), SILC_STR_END) < 0) goto err; silc_mp_init(&dq); silc_mp_bin2mp(tmp, len, &dq); silc_buffer_pull(&k, len); - if (ver != SILC_PRIVATE_KEY_VERSION_1) { + if (ver == 0) { /* Old version */ /* Get pQ len */ @@ -1106,7 +1184,7 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, goto err; silc_buffer_pull(&k, 4); if (silc_buffer_unformat(&k, - SILC_STR_UI_XNSTRING(&tmp, len), + SILC_STR_DATA(&tmp, len), SILC_STR_END) < 0) goto err; silc_mp_init(&qp); @@ -1121,7 +1199,7 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, goto err; silc_buffer_pull(&k, 4); if (silc_buffer_unformat(&k, - SILC_STR_UI_XNSTRING(&tmp, len), + SILC_STR_DATA(&tmp, len), SILC_STR_END) < 0) goto err; silc_mp_init(&p); @@ -1135,14 +1213,14 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, goto err; silc_buffer_pull(&k, 4); if (silc_buffer_unformat(&k, - SILC_STR_UI_XNSTRING(&tmp, len), + SILC_STR_DATA(&tmp, len), SILC_STR_END) < 0) goto err; silc_mp_init(&q); silc_mp_bin2mp(tmp, len, &q); silc_buffer_pull(&k, len); - if (ver != SILC_PRIVATE_KEY_VERSION_1) { + if (ver == 0) { /* Old version. Compute to new version */ SILC_LOG_DEBUG(("Old version private key")); silc_mp_init(&qp); @@ -1185,24 +1263,24 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key, } /* Import PKCS algorithm private key */ - if (pkcs->import_private_key) - if (!pkcs->import_private_key(alg_key.data, silc_buffer_len(&alg_key), - &silc_privkey->private_key)) - goto err; + if (!pkcs->import_private_key(alg_key.data, silc_buffer_len(&alg_key), + &silc_privkey->private_key)) + goto err; silc_free(pkcs_name); silc_asn1_free(asn1); *ret_private_key = silc_privkey; - return TRUE; + return key_len; err: silc_free(pkcs_name); silc_free(silc_privkey); if (asn1) silc_asn1_free(asn1); - return FALSE; + SILC_LOG_ERROR(("Malformed SILC private key ")); + return 0; } /* Exports private key as SILC implementation style private key file */ @@ -1334,7 +1412,7 @@ silc_pkcs_silc_export_private_key_file(void *private_key, break; case SILC_PKCS_FILE_BASE64: - data = silc_pem_encode_file(enc->data, silc_buffer_len(enc)); + data = silc_base64_encode_file(enc->data, silc_buffer_len(enc)); if (!data) { silc_buffer_clear(enc); silc_buffer_free(enc); @@ -1529,7 +1607,8 @@ SilcBool silc_pkcs_silc_encrypt(void *public_key, SilcUInt32 src_len, unsigned char *dst, SilcUInt32 dst_size, - SilcUInt32 *ret_dst_len) + SilcUInt32 *ret_dst_len, + SilcRng rng) { SilcSILCPublicKey silc_pubkey = public_key; @@ -1538,7 +1617,7 @@ SilcBool silc_pkcs_silc_encrypt(void *public_key, return silc_pubkey->pkcs->encrypt(silc_pubkey->public_key, src, src_len, - dst, dst_size, ret_dst_len); + dst, dst_size, ret_dst_len, rng); } /* Decrypts as specified in SILC protocol specification */ @@ -1568,6 +1647,7 @@ SilcBool silc_pkcs_silc_sign(void *private_key, unsigned char *signature, SilcUInt32 signature_size, SilcUInt32 *ret_signature_len, + SilcBool compute_hash, SilcHash hash) { SilcSILCPrivateKey silc_privkey = private_key; @@ -1578,7 +1658,7 @@ SilcBool silc_pkcs_silc_sign(void *private_key, return silc_privkey->pkcs->sign(silc_privkey->private_key, src, src_len, signature, signature_size, - ret_signature_len, hash); + ret_signature_len, compute_hash, hash); } /* Verifies as specified in SILC protocol specification */