From: Pekka Riikonen Date: Tue, 14 Jan 2003 11:43:37 +0000 (+0000) Subject: Added silc_buffer_steal. Optimized some encoding and decoding X-Git-Tag: silc.client.0.9.11.1~14 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=db19af860f011d4e3fae2de6df211fa4648d3809;p=silc.git Added silc_buffer_steal. Optimized some encoding and decoding routines. --- diff --git a/CHANGES b/CHANGES index 7f532718..4a253690 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +Tue Jan 14 12:25:09 CET 2003 Pekka Riikonen + + * Added silc_buffer_steal to steal the data from the buffer. + Affected file lib/silcutil/silcbuffer.h. + Sat Jan 11 18:16:29 CET 2003 Giovanni Giacobbi * Fixed server crash with double Primary block in config file. diff --git a/lib/silccore/silcauth.c b/lib/silccore/silcauth.c index 38a1a961..d42dd66f 100644 --- a/lib/silccore/silcauth.c +++ b/lib/silccore/silcauth.c @@ -216,14 +216,8 @@ silc_auth_public_key_encode_data(SilcPublicKey public_key, SILC_STR_UI_XNSTRING(pk, pk_len), SILC_STR_END); - ret = silc_memdup(buf->data, buf->len); - if (!ret) - return NULL; - - if (ret_len) - *ret_len = buf->len; + ret = silc_buffer_steal(buf, ret_len); - silc_buffer_clear(buf); silc_buffer_free(buf); silc_free(id_data); silc_free(pk); diff --git a/lib/silccrypt/silcpkcs.c b/lib/silccrypt/silcpkcs.c index 4deddfd9..83a16d00 100644 --- a/lib/silccrypt/silcpkcs.c +++ b/lib/silccrypt/silcpkcs.c @@ -687,8 +687,9 @@ silc_pkcs_public_key_encode(SilcPublicKey public_key, SilcUInt32 *len) SilcBuffer buf; unsigned char *ret; - buf = silc_buffer_alloc(public_key->len + 4); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); + buf = silc_buffer_alloc_size(public_key->len + 4); + if (!buf) + return NULL; silc_buffer_format(buf, SILC_STR_UI_INT(public_key->len), @@ -699,13 +700,9 @@ silc_pkcs_public_key_encode(SilcPublicKey public_key, SilcUInt32 *len) SILC_STR_UI_XNSTRING(public_key->pk, public_key->pk_len), SILC_STR_END); - if (len) - *len = public_key->len + 4; - ret = silc_calloc(buf->len, sizeof(*ret)); - memcpy(ret, buf->data, buf->len); + ret = silc_buffer_steal(buf, len); silc_buffer_free(buf); - return ret; } @@ -721,8 +718,9 @@ silc_pkcs_public_key_data_encode(unsigned char *pk, SilcUInt32 pk_len, SilcUInt32 totlen; totlen = 2 + strlen(pkcs) + 2 + strlen(identifier) + pk_len; - buf = silc_buffer_alloc(totlen + 4); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); + buf = silc_buffer_alloc_size(totlen + 4); + if (!buf) + return NULL; silc_buffer_format(buf, SILC_STR_UI_INT(totlen), @@ -732,13 +730,9 @@ silc_pkcs_public_key_data_encode(unsigned char *pk, SilcUInt32 pk_len, SILC_STR_UI32_STRING(identifier), SILC_STR_UI_XNSTRING(pk, pk_len), SILC_STR_END); - if (len) - *len = totlen + 4; - ret = silc_calloc(buf->len, sizeof(*ret)); - memcpy(ret, buf->data, buf->len); + ret = silc_buffer_steal(buf, len); silc_buffer_free(buf); - return ret; } @@ -748,40 +742,34 @@ silc_pkcs_public_key_data_encode(unsigned char *pk, SilcUInt32 pk_len, bool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len, SilcPublicKey *public_key) { - SilcBuffer buf; + SilcBufferStruct buf; SilcPKCS alg; SilcUInt16 pkcs_len, identifier_len; SilcUInt32 totlen, key_len; unsigned char *pkcs_name = NULL, *ident = NULL, *key_data = NULL; int ret; - buf = silc_buffer_alloc(data_len); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); - silc_buffer_put(buf, data, data_len); + silc_buffer_set(&buf, data, data_len); /* Get length */ - ret = silc_buffer_unformat(buf, + ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&totlen), SILC_STR_END); - if (ret == -1) { - silc_buffer_free(buf); + if (ret == -1) return FALSE; - } #if 1 /* Backwards support, remove! */ if (totlen == data_len) totlen -= 4; #endif - if (totlen + 4 != data_len) { - silc_buffer_free(buf); + if (totlen + 4 != data_len) return FALSE; - } /* Get algorithm name and identifier */ - silc_buffer_pull(buf, 4); + silc_buffer_pull(&buf, 4); ret = - silc_buffer_unformat(buf, + silc_buffer_unformat(&buf, SILC_STR_UI16_NSTRING_ALLOC(&pkcs_name, &pkcs_len), SILC_STR_UI16_NSTRING_ALLOC(&ident, &identifier_len), SILC_STR_END); @@ -807,9 +795,9 @@ bool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len, } /* 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; - ret = silc_buffer_unformat(buf, + silc_buffer_pull(&buf, 2 + pkcs_len + 2 + identifier_len); + key_len = buf.len; + ret = silc_buffer_unformat(&buf, SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len), SILC_STR_END); if (ret == -1) @@ -835,17 +823,12 @@ bool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len, (*public_key)->pk_type = SILC_SKE_PK_TYPE_SILC; } - silc_buffer_free(buf); return TRUE; err: - if (pkcs_name) - silc_free(pkcs_name); - if (ident) - silc_free(ident); - if (key_data) - silc_free(key_data); - silc_buffer_free(buf); + silc_free(pkcs_name); + silc_free(ident); + silc_free(key_data); return FALSE; } @@ -971,8 +954,9 @@ silc_pkcs_private_key_encode(SilcPrivateKey private_key, SilcUInt32 *len) SilcUInt32 totlen; totlen = 2 + strlen(private_key->name) + private_key->prv_len; - buf = silc_buffer_alloc(totlen); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); + buf = silc_buffer_alloc_size(totlen); + if (!buf) + return NULL; silc_buffer_format(buf, SILC_STR_UI_SHORT(strlen(private_key->name)), @@ -980,14 +964,9 @@ silc_pkcs_private_key_encode(SilcPrivateKey private_key, SilcUInt32 *len) SILC_STR_UI_XNSTRING(private_key->prv, private_key->prv_len), SILC_STR_END); - if (len) - *len = totlen; - ret = silc_calloc(buf->len, sizeof(*ret)); - memcpy(ret, buf->data, buf->len); - silc_buffer_clear(buf); + ret = silc_buffer_steal(buf, len); silc_buffer_free(buf); - return ret; } @@ -1002,22 +981,18 @@ silc_pkcs_private_key_data_encode(unsigned char *prv, SilcUInt32 prv_len, SilcUInt32 totlen; totlen = 2 + strlen(pkcs) + prv_len; - buf = silc_buffer_alloc(totlen); - silc_buffer_pull_tail(buf, totlen); + buf = silc_buffer_alloc_size(totlen); + if (!buf) + return NULL; silc_buffer_format(buf, SILC_STR_UI_SHORT(strlen(pkcs)), SILC_STR_UI32_STRING(pkcs), SILC_STR_UI_XNSTRING(prv, prv_len), SILC_STR_END); - if (len) - *len = totlen; - ret = silc_calloc(buf->len, sizeof(*ret)); - memcpy(ret, buf->data, buf->len); - silc_buffer_clear(buf); + ret = silc_buffer_steal(buf, len); silc_buffer_free(buf); - return ret; } @@ -1027,20 +1002,18 @@ silc_pkcs_private_key_data_encode(unsigned char *prv, SilcUInt32 prv_len, bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len, SilcPrivateKey *private_key) { - SilcBuffer buf; + SilcBufferStruct buf; SilcPKCS alg; SilcUInt16 pkcs_len; SilcUInt32 key_len; unsigned char *pkcs_name = NULL, *key_data = NULL; int ret; - buf = silc_buffer_alloc(data_len); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); - silc_buffer_put(buf, data, data_len); + silc_buffer_set(&buf, data, data_len); /* Get algorithm name and identifier */ ret = - silc_buffer_unformat(buf, + silc_buffer_unformat(&buf, SILC_STR_UI16_NSTRING_ALLOC(&pkcs_name, &pkcs_len), SILC_STR_END); if (ret == -1) { @@ -1048,7 +1021,7 @@ bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len, goto err; } - if (pkcs_len < 1 || pkcs_len > buf->truelen) { + if (pkcs_len < 1 || pkcs_len > buf.truelen) { SILC_LOG_DEBUG(("Malformed private key buffer")); goto err; } @@ -1060,9 +1033,9 @@ bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len, } /* Get key data. We assume that rest of the buffer is key data. */ - silc_buffer_pull(buf, 2 + pkcs_len); - key_len = buf->len; - ret = silc_buffer_unformat(buf, + silc_buffer_pull(&buf, 2 + pkcs_len); + key_len = buf.len; + ret = silc_buffer_unformat(&buf, SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len), SILC_STR_END); if (ret == -1) @@ -1087,17 +1060,11 @@ bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len, (*private_key)->prv_len = key_len; } - silc_buffer_clear(buf); - silc_buffer_free(buf); return TRUE; err: - if (pkcs_name) - silc_free(pkcs_name); - if (key_data) - silc_free(key_data); - silc_buffer_clear(buf); - silc_buffer_free(buf); + silc_free(pkcs_name); + silc_free(key_data); return FALSE; } @@ -1110,20 +1077,24 @@ static bool silc_pkcs_save_public_key_internal(const char *filename, { SilcBuffer buf; SilcUInt32 len; + unsigned char *tmp = NULL; switch(encoding) { case SILC_PKCS_FILE_BIN: break; case SILC_PKCS_FILE_PEM: - data = silc_pem_encode_file(data, data_len); + tmp = data = silc_pem_encode_file(data, data_len); data_len = strlen(data); break; } len = data_len + (strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN) + strlen(SILC_PKCS_PUBLIC_KEYFILE_END)); - buf = silc_buffer_alloc(len); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); + buf = silc_buffer_alloc_size(len); + if (!buf) { + silc_free(tmp); + return FALSE; + } silc_buffer_format(buf, SILC_STR_UI32_STRING(SILC_PKCS_PUBLIC_KEYFILE_BEGIN), @@ -1133,10 +1104,12 @@ static bool silc_pkcs_save_public_key_internal(const char *filename, /* Save into file */ if (silc_file_writefile(filename, buf->data, buf->len)) { + silc_free(tmp); silc_buffer_free(buf); return FALSE; } + silc_free(tmp); silc_buffer_free(buf); return TRUE; } diff --git a/lib/silcutil/silcbuffer.h b/lib/silcutil/silcbuffer.h index b8463044..7b3b13cc 100644 --- a/lib/silcutil/silcbuffer.h +++ b/lib/silcutil/silcbuffer.h @@ -210,13 +210,43 @@ void silc_buffer_free(SilcBuffer sb) { if (sb) { #if defined(SILC_DEBUG) - memset(sb->head, 'F', sb->truelen); + if (sb->head) + memset(sb->head, 'F', sb->truelen); #endif silc_free(sb->head); silc_free(sb); } } +/****f* silcutil/SilcBufferAPI/silc_buffer_steal + * + * SYNOPSIS + * + * static inline + * unsigned char *silc_buffer_free(SilcBuffer sb, SilcUInt32 *data_len); + * + * DESCRIPTION + * + * Steals the data from the buffer `sb'. This returns pointer to the + * start of the buffer and the true length of that buffer. The `sb' + * cannot be used anymore after calling this function because the + * data buffer was stolen. The `sb' must be freed with silc_buffer_free. + * The caller is responsible of freeing the stolen data buffer with + * silc_free. + * + ***/ + +static inline +unsigned char *silc_buffer_steal(SilcBuffer sb, SilcUInt32 *data_len) +{ + unsigned char *buf = sb->head; + if (data_len) + *data_len = sb->truelen; + sb->head = sb->data = sb->tail = sb->end = NULL; + sb->len = sb->truelen = 0; + return buf; +} + /****f* silcutil/SilcBufferAPI/silc_buffer_set * * SYNOPSIS diff --git a/lib/silcutil/win32/silcwin32schedule.c b/lib/silcutil/win32/silcwin32schedule.c index 22445aef..671b1268 100644 --- a/lib/silcutil/win32/silcwin32schedule.c +++ b/lib/silcutil/win32/silcwin32schedule.c @@ -52,7 +52,7 @@ int silc_select(SilcScheduleFd fds, SilcUInt32 fds_count, struct timeval *timeout) { - HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + static HANDLE handles[MAXIMUM_WAIT_OBJECTS]; DWORD ready, curtime, timeo; int nhandles = 0, i; MSG msg; @@ -83,27 +83,17 @@ int silc_select(SilcScheduleFd fds, SilcUInt32 fds_count, struct timeval *timeou and wait just for windows messages. */ if (nhandles == 0 && timeout) { UINT timer = SetTimer(NULL, 0, timeo, NULL); - curtime = GetTickCount(); - while (timer) { - WaitMessage(); - - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_TIMER) { - KillTimer(NULL, timer); - return 0; - } - TranslateMessage(&msg); - DispatchMessage(&msg); - } + GetMessage(&msg, NULL, 0, 0); + if (msg.message == WM_TIMER) { KillTimer(NULL, timer); - if (timeo != INFINITE) { - timeo -= GetTickCount() - curtime; - if (timeo < 0) - timeo = 0; - } - timer = SetTimer(NULL, 0, timeo, NULL); + return 0; } + TranslateMessage(&msg); + DispatchMessage(&msg); + + KillTimer(NULL, timer); + timeo = 0; } retry: