+Thu Nov 8 22:21:09 EET 2001 Pekka Riikonen <priikone@silcnet.org>
+
+ * Call check_version SKE callback for initiator too. Affected
+ file lib/silcske/silcske.c.
+
+ * Implemented fix for security hole found in the SKE that was
+ fixed in the specification few days back; the initiator's
+ public key is now added to the HASH value computation.
+ Added backwards support for the old way of doing it too, for
+ old clients and old servers. Affected file is
+ lib/silcske/silcske.c.
+
+ * Enabled mutual authentication by default in SKE. If initiator
+ is not providing mutual authentication the responder will
+ force it. This will provide the proof of posession of the
+ private key for responder. The affected files are
+ lib/silcclient/protocol.c and silcd/protocol.c.
+
+ * Do not cache anymore the server's public key during SKE.
+ We do mutual authentication so the proof of posession of
+ private key is done, and if the server is authenticated in
+ conn auth protocol with public key we must have the public
+ key already. Affected file silcd/protocol.c.
+
+ * Added new global debug variable: silc_debug_hexdump. If
+ it is set to TRUE SILC_LOG_HEXDUMP will be printed. Affected
+ file lib/silcutil/silclog.[ch].
+
+ * Fixed compilation warning due to char * -> const char *.
+ Affected files lib/silcutil/silcnet.h, and
+ lib/silccore/silcauth.[ch].
+
Wed Nov 7 20:43:03 EET 2001 Pekka Riikonen <priikone@silcnet.org>
* Fixed CMODE command when new channel key was created. If
TODO/bugs In SILC Client Library
================================
- o JOIN command's argument handling is buggy. See the XXX in the code.
-
o key agreement with itself causes the packet sequence numbers go grazy.
+ o WHOIS shows the formatted nickname wrong in some circumstances.
+
+ o JOIN command's argument handling is buggy. See the XXX in the code.
+
TODO/bugs In SILC Server
========================
nice as SSH is widely used all over the place. SILC Protocol
supports SSH2 public keys.
+ o OpenPGP certificate support.
+
o Cipher optimizations (asm, that this) at least for i386 would be nice.
SilcClient silc_client = NULL;
SilcClientConfig silc_config = NULL;
extern SilcClientOperations ops;
-extern int silc_debug;
+extern bool silc_debug;
+extern bool silc_debug_hexdump;
#ifdef SILC_SIM
/* SIM (SILC Module) table */
SilcSimContext **sims = NULL;
if (opt_debug) {
silc_debug = TRUE;
+ silc_debug_hexdump = TRUE;
silc_log_set_debug_string(opt_debug);
silc_log_set_callbacks(silc_log_info, silc_log_warning,
silc_log_error, NULL);
return TRUE;
}
+ /* XXX For now, accept server keys without verification too. We are
+ currently always doing mutual authentication so the proof of posession
+ of the private key is verified, and if server is authenticated in
+ conn auth protocol with public key we MUST have the key already. */
+ return TRUE;
+ /* Rest is unreachable code! */
+
memset(filename, 0, sizeof(filename));
memset(file, 0, sizeof(file));
snprintf(file, sizeof(file) - 1, "serverkey_%s_%d.pub", sock->hostname,
if (maj == 0 && min < 5)
status = SILC_SKE_STATUS_BAD_VERSION;
+ /* XXX backward support for 0.6.1 */
+ if (maj == 0 && min == 6 && build < 2)
+ ske->backward_version = 1;
+
return status;
}
properties packet from initiator. */
status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
silc_version_string,
- ctx->packet->buffer, FALSE);
+ ctx->packet->buffer, TRUE);
} else {
SilcSKEStartPayload *start_payload;
/* Assemble security properties. */
- silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
+ silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_MUTUAL,
silc_version_string,
&start_payload);
\n\
Generic Options:\n\
-f --config-file=FILE Alternate configuration file\n\
- -d --debug Enable debugging (no daemon)\n\
+ -d --debug=string Enable debugging (no daemon)\n\
-h --help Display this message\n\
-V --version Display version\n\
\n\
break;
case 'd':
silc_debug = TRUE;
+ silc_debug_hexdump = TRUE;
silc_log_set_debug_string(optarg);
break;
case 'f':
.hy 0
.in 0
.nf
-Network Working Group P. Riikonen
+Network Working Group P. Riikonen
Internet-Draft
draft-riikonen-silc-commands-02.txt XXX
Expires: XXX
.ds RF FORMFEED[Page %]
.ds CF
.ds LH Internet-Draft
-.ds RH XXX
+.ds RH 13 November 2001
.ds CH
.na
.hy 0
.in 0
.nf
-Network Working Group P. Riikonen
+Network Working Group P. Riikonen
Internet-Draft
-draft-riikonen-silc-ke-auth-04.txt XXX
-Expires: XXX
+draft-riikonen-silc-ke-auth-04.txt 13 November 2001
+Expires: 13 May 2002
.in 3
2.5 Key Exchange Status Types ................................. 15
3 SILC Connection Authentication Protocol ....................... 16
3.1 Connection Auth Payload ................................... 18
- 3.2 Connection Authentication Types ........................... 18
+ 3.2 Connection Authentication Types ........................... 19
3.2.1 Passphrase Authentication ........................... 19
3.2.2 Public Key Authentication ........................... 19
- 3.3 Connection Authentication Status Types .................... 19
+ 3.3 Connection Authentication Status Types .................... 20
4 Security Considerations ....................................... 20
5 References .................................................... 20
-6 Author's Address .............................................. 21
+6 Author's Address .............................................. 22
.ti 0
.in 3
+
+
.ti 0
3.2 Connection Authentication Types
auth_hash = hash(HASH | Key Exchange Start Payload);
signature = sign(auth_hash);
-The hash() function used to compute the value is the hash function negotiated
-in the SKE protocol. The server MUST verify the data, thus it must keep
-the HASH and the Key Exchange Start Payload saved during SKE and
-authentication protocols.
+The hash() function used to compute the value is the hash function
+negotiated in the SKE protocol. The server MUST verify the data, thus
+it must keep the HASH and the Key Exchange Start Payload saved during
+SKE and authentication protocols.
If the verified signature matches the sent signature, the authentication
-were successful and SILC_PACKET_SUCCESS is sent. If it failed the protocol
-execution is stopped and SILC_PACKET_FAILURE is sent.
+were successful and SILC_PACKET_SUCCESS is sent. If it failed the
+protocol execution is stopped and SILC_PACKET_FAILURE is sent.
This is REQUIRED authentication method to be supported by all SILC
implementations.
EMail: priikone@silcnet.org
-This Internet-Draft expires XXX
+This Internet-Draft expires 13 May 2002
.ds RF FORMFEED[Page %]
.ds CF
.ds LH Internet Draft
-.ds RH XXX
+.ds RH 13 November 2001
.ds CH
.na
.hy 0
.in 0
.nf
-Network Working Group P. Riikonen
+Network Working Group P. Riikonen
Internet-Draft
-draft-riikonen-silc-pp-04.txt XXX
-Expires: XXX
+draft-riikonen-silc-pp-04.txt 13 November 2001
+Expires: 13 May 2002
.in 3
[RFC2119] Bradner, S., "Key Words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
+[SFTP] Ylonen T., and Lehtinen S., "Secure Shell File Transfer
+ Protocol", Internet Draft, March 2001.
.ti 0
5 Author's Address
EMail: priikone@silcnet.org
-This Internet-Draft expires XXX
+This Internet-Draft expires 13 May 2002
.hy 0
.in 0
.nf
-Network Working Group P. Riikonen
+Network Working Group P. Riikonen
Internet-Draft
-draft-riikonen-silc-spec-04.txt 13 November 2001
+draft-riikonen-silc-spec-04.txt 13 November 2001
Expires: 13 May 2002
.in 3
if (hostname) {
ke = silc_calloc(1, sizeof(*ke));
- if (bindhost) {
+ if (bindhost)
ke->fd = silc_net_create_server(port, bindhost);
- }
- else {
- ke->fd = silc_net_create_server(port, hostname);
- }
+ else
+ ke->fd = silc_net_create_server(port, hostname);
if (ke->fd < 0) {
client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
if (maj != maj2)
status = SILC_SKE_STATUS_BAD_VERSION;
- if (min < min2)
- status = SILC_SKE_STATUS_BAD_VERSION;
+
+ /* XXX backward support for 0.6.1 */
+ if (maj == 0 && min == 6 && build < 2)
+ ske->backward_version = 1;
if (status != SILC_SKE_STATUS_OK)
client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
SilcSKEStartPayload *start_payload;
/* Assemble security properties. */
- silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE,
+ silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_MUTUAL,
client->silc_client_version,
&start_payload);
/* Encodes the Key Agreement protocol and returns the encoded buffer */
-SilcBuffer silc_key_agreement_payload_encode(char *hostname,
+SilcBuffer silc_key_agreement_payload_encode(const char *hostname,
uint32 port)
{
SilcBuffer buffer;
* Encodes the Key Agreement protocol and returns the encoded buffer
*
***/
-SilcBuffer silc_key_agreement_payload_encode(char *hostname,
+SilcBuffer silc_key_agreement_payload_encode(const char *hostname,
uint32 port);
/****f* silccore/SilcAuthAPI/silc_key_agreement_payload_free
return status;
}
+ /* Check version string */
+ if (ske->callbacks->check_version) {
+ status = ske->callbacks->check_version(ske, payload->version,
+ payload->version_len,
+ ske->callbacks->context);
+ if (status != SILC_SKE_STATUS_OK) {
+ ske->status = status;
+ silc_ske_payload_start_free(ske->start_payload);
+ return status;
+ }
+ }
+
/* Free our KE Start Payload context, we don't need it anymore. */
silc_ske_payload_start_free(ske->start_payload);
/* Send the packet. */
if (ske->callbacks->send_packet)
(*ske->callbacks->send_packet)(ske, payload_buf, SILC_PACKET_KEY_EXCHANGE,
- ske->callbacks->context);
+ ske->callbacks->context);
silc_buffer_free(payload_buf);
f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
- buf = silc_buffer_alloc(ske->start_payload_copy->len +
- ske->ke2_payload->pk_len + e_len +
- f_len + KEY_len);
- silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
-
/* Format the buffer used to compute the hash value */
- ret =
- silc_buffer_format(buf,
- SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
- ske->start_payload_copy->len),
- SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
- ske->ke2_payload->pk_len),
- SILC_STR_UI_XNSTRING(e, e_len),
- SILC_STR_UI_XNSTRING(f, f_len),
- SILC_STR_UI_XNSTRING(KEY, KEY_len),
- SILC_STR_END);
+ /* XXX Backward support for 0.6.1 */
+ if (ske->backward_version == 1) {
+ SILC_LOG_DEBUG(("*********** Using old KE payload"));
+ buf = silc_buffer_alloc(ske->start_payload_copy->len +
+ ske->ke2_payload->pk_len + e_len +
+ f_len + KEY_len);
+ silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
+
+ ret =
+ silc_buffer_format(buf,
+ SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
+ ske->start_payload_copy->len),
+ SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
+ ske->ke2_payload->pk_len),
+ SILC_STR_UI_XNSTRING(e, e_len),
+ SILC_STR_UI_XNSTRING(f, f_len),
+ SILC_STR_UI_XNSTRING(KEY, KEY_len),
+ SILC_STR_END);
+ } else {
+ /* Initiator is not required to send its public key */
+ SILC_LOG_DEBUG(("*********** Using new KE payload"));
+ buf = silc_buffer_alloc(ske->start_payload_copy->len +
+ ske->ke2_payload->pk_len +
+ ske->ke1_payload->pk_len +
+ e_len + f_len + KEY_len);
+ silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
+
+ if (!ske->ke1_payload->pk_data) {
+ ret =
+ silc_buffer_format(buf,
+ SILC_STR_UI_XNSTRING(ske->start_payload_copy->
+ data,
+ ske->start_payload_copy->
+ len),
+ SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
+ ske->ke2_payload->pk_len),
+ SILC_STR_UI_XNSTRING(e, e_len),
+ SILC_STR_UI_XNSTRING(f, f_len),
+ SILC_STR_UI_XNSTRING(KEY, KEY_len),
+ SILC_STR_END);
+ } else {
+ ret =
+ silc_buffer_format(buf,
+ SILC_STR_UI_XNSTRING(ske->start_payload_copy->
+ data,
+ ske->start_payload_copy->
+ len),
+ SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
+ ske->ke2_payload->pk_len),
+ SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
+ ske->ke1_payload->pk_len),
+ SILC_STR_UI_XNSTRING(e, e_len),
+ SILC_STR_UI_XNSTRING(f, f_len),
+ SILC_STR_UI_XNSTRING(KEY, KEY_len),
+ SILC_STR_END);
+ }
+ }
if (ret == -1) {
silc_buffer_free(buf);
memset(e, 0, e_len);
#include "silcincludes.h"
/* Set TRUE/FALSE to enable/disable debugging */
-int silc_debug = FALSE;
+bool silc_debug = FALSE;
+bool silc_debug_hexdump = FALSE;
char *silc_debug_string = NULL;
/* SILC Log name strings. These strings are printed to the log file. */
int off, pos, count;
unsigned char *data = (unsigned char *)data_in;
- if (!silc_debug) {
+ if (!silc_debug_hexdump) {
silc_free(string);
return;
}
void silc_log_set_debug_string(const char *debug_string)
{
silc_free(silc_debug_string);
- silc_debug_string = silc_string_regexify(debug_string);
+ if (strchr(debug_string, '(') &&
+ strchr(debug_string, ')'))
+ silc_debug_string = strdup(debug_string);
+ else
+ silc_debug_string = silc_string_regexify(debug_string);
}
#define SILCLOG_H
/* Set TRUE/FALSE to enable/disable debugging */
-extern int silc_debug;
+extern bool silc_debug;
+extern bool silc_debug_hexdump;
extern char *silc_debug_string;
/* SILC Log types */
* the created socket or -1 on error.
*
***/
-int silc_net_create_server(int port, char *ip_addr);
+int silc_net_create_server(int port, const char *ip_addr);
/****f* silcutil/SilcNetAPI/silc_net_close_server
*
If argument `ip_addr' is NULL `any' address will be used. Returns
the created socket or -1 on error. */
-int silc_net_create_server(int port, char *ip_addr)
+int silc_net_create_server(int port, const char *ip_addr)
{
int sock, rval;
struct sockaddr_in server;
If argument `ip_addr' is NULL `any' address will be used. Returns
the created socket or -1 on error. */
-int silc_net_create_server(int port, char *ip_addr)
+int silc_net_create_server(int port, const char *ip_addr)
{
SOCKET sock;
int rval;