Conflicts:
	configure.ac
This commit is contained in:
Fabian Freyer
2014-09-25 23:50:29 +02:00
21 changed files with 552 additions and 106 deletions

View File

@@ -1,3 +1,5 @@
0.8.5
- libtoolize to generate .so
TBA
- SCRAM-SHA-1 authentication mechanism
0.8.5
- libtoolize to generate .so

View File

@@ -14,15 +14,18 @@ STROPHE_LIBS = libstrophe.la
## Main build targets
lib_LTLIBRARIES = libstrophe.la
libstrophe_la_CFLAGS=$(STROPHE_FLAGS) $(PARSER_CFLAGS)
libstrophe_la_LDFLAGS=$(SSL_LIBS) $(PARSER_LIBS)
libstrophe_la_CFLAGS = $(STROPHE_FLAGS) $(PARSER_CFLAGS)
libstrophe_la_LDFLAGS = $(SSL_LIBS) $(PARSER_LIBS)
# Export only public API
libstrophe_la_LDFLAGS += -export-symbols-regex '^xmpp_'
libstrophe_la_SOURCES = src/auth.c src/conn.c src/ctx.c \
src/event.c src/handler.c src/hash.c \
src/jid.c src/md5.c src/sasl.c src/sha1.c \
src/jid.c src/md5.c src/sasl.c src/scram.c src/sha1.c \
src/snprintf.c src/sock.c src/stanza.c src/thread.c \
src/tls_openssl.c src/util.c \
src/common.h src/hash.h src/md5.h src/ostypes.h src/parser.h \
src/sasl.h src/sha1.h src/sock.h src/thread.h src/tls.h src/util.h
src/sasl.h src/scram.h src/sha1.h src/sock.h src/thread.h src/tls.h \
src/util.h
if PARSER_EXPAT
libstrophe_la_SOURCES += src/parser_expat.c

View File

@@ -1,4 +1,4 @@
AC_INIT([libstrophe], [0.8.5], [jack@metajack.im])
AC_INIT([libstrophe], [0.8.7], [jack@metajack.im])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign])
LT_INIT([dlopen])

View File

@@ -19,12 +19,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "strophe.h"
#include "common.h"
#include "sasl.h"
#ifdef _WIN32
#ifdef _MSC_VER
#define strcasecmp stricmp
#endif
@@ -74,6 +75,10 @@ static int _handle_digestmd5_challenge(xmpp_conn_t * const conn,
static int _handle_digestmd5_rspauth(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza,
void * const userdata);
static int _handle_scram_sha1_challenge(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza,
void * const userdata);
static char *_make_scram_sha1_init_msg(xmpp_conn_t * const conn);
static int _handle_missing_features_sasl(xmpp_conn_t * const conn,
void * const userdata);
@@ -228,6 +233,8 @@ static int _handle_features(xmpp_conn_t * const conn,
conn->sasl_support |= SASL_MASK_PLAIN;
else if (strcasecmp(text, "DIGEST-MD5") == 0)
conn->sasl_support |= SASL_MASK_DIGESTMD5;
else if (strcasecmp(text, "SCRAM-SHA-1") == 0)
conn->sasl_support |= SASL_MASK_SCRAMSHA1;
else if (strcasecmp(text, "ANONYMOUS") == 0)
conn->sasl_support |= SASL_MASK_ANONYMOUS;
@@ -415,6 +422,117 @@ static int _handle_digestmd5_rspauth(xmpp_conn_t * const conn,
return 1;
}
/* handle the challenge phase of SCRAM-SHA-1 auth */
static int _handle_scram_sha1_challenge(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza,
void * const userdata)
{
char *text;
char *response;
xmpp_stanza_t *auth, *authdata;
char *name;
char *challenge;
char *scram_init = (char *)userdata;
name = xmpp_stanza_get_name(stanza);
xmpp_debug(conn->ctx, "xmpp",
"handle SCRAM-SHA-1 (challenge) called for %s", name);
if (strcmp(name, "challenge") == 0) {
text = xmpp_stanza_get_text(stanza);
if (!text)
goto err;
challenge = (char *)base64_decode(conn->ctx, text, strlen(text));
xmpp_free(conn->ctx, text);
if (!challenge)
goto err;
response = sasl_scram_sha1(conn->ctx, challenge, scram_init,
conn->jid, conn->pass);
xmpp_free(conn->ctx, challenge);
if (!response)
goto err;
auth = xmpp_stanza_new(conn->ctx);
if (!auth)
goto err_free_response;
xmpp_stanza_set_name(auth, "response");
xmpp_stanza_set_ns(auth, XMPP_NS_SASL);
authdata = xmpp_stanza_new(conn->ctx);
if (!authdata)
goto err_release_auth;
xmpp_stanza_set_text(authdata, response);
xmpp_free(conn->ctx, response);
xmpp_stanza_add_child(auth, authdata);
xmpp_stanza_release(authdata);
xmpp_send(conn, auth);
xmpp_stanza_release(auth);
} else {
xmpp_free(conn->ctx, scram_init);
return _handle_sasl_result(conn, stanza, "SCRAM-SHA-1");
}
return 1;
err_release_auth:
xmpp_stanza_release(auth);
err_free_response:
xmpp_free(conn->ctx, response);
err:
xmpp_free(conn->ctx, scram_init);
disconnect_mem_error(conn);
return 0;
}
static char *_get_nonce(xmpp_ctx_t *ctx)
{
unsigned char buffer[sizeof(clock_t) + sizeof(time_t)] = {0};
clock_t ticks = clock();
time_t t;
if (ticks != (clock_t)-1) {
*(clock_t *)buffer = ticks;
}
t = time((time_t *)(buffer + sizeof(clock_t)));
if (t == (time_t)-1) {
*(time_t *)(buffer + sizeof(clock_t)) = (time_t)rand();
}
return base64_encode(ctx, buffer, sizeof(buffer));
}
static char *_make_scram_sha1_init_msg(xmpp_conn_t * const conn)
{
size_t message_len;
char *node;
char *message;
char *nonce;
node = xmpp_jid_node(conn->ctx, conn->jid);
if (!node) {
return NULL;
}
nonce = _get_nonce(conn->ctx);
if (!nonce) {
return NULL;
}
message_len = strlen(node) + strlen(nonce) + 8 + 1;
message = xmpp_alloc(conn->ctx, message_len);
if (message) {
xmpp_snprintf(message, message_len, "n,,n=%s,r=%s", node, nonce);
xmpp_free(conn->ctx, node);
}
xmpp_free(conn->ctx, nonce);
return message;
}
static xmpp_stanza_t *_make_starttls(xmpp_conn_t * const conn)
{
xmpp_stanza_t *starttls;
@@ -454,6 +572,7 @@ static void _auth(xmpp_conn_t * const conn)
{
xmpp_stanza_t *auth, *authdata, *query, *child, *iq;
char *str, *authid;
char *scram_init;
int anonjid;
/* if there is no node in conn->jid, we assume anonymous connect */
@@ -516,6 +635,51 @@ static void _auth(xmpp_conn_t * const conn)
xmpp_error(conn->ctx, "auth",
"No node in JID, and SASL ANONYMOUS unsupported.");
xmpp_disconnect(conn);
} else if (conn->sasl_support & SASL_MASK_SCRAMSHA1) {
auth = _make_sasl_auth(conn, "SCRAM-SHA-1");
if (!auth) {
disconnect_mem_error(conn);
return;
}
/* don't free scram_init on success */
scram_init = _make_scram_sha1_init_msg(conn);
if (!scram_init) {
xmpp_stanza_release(auth);
disconnect_mem_error(conn);
return;
}
str = (char *)base64_encode(conn->ctx, (unsigned char *)scram_init,
strlen(scram_init));
if (!str) {
xmpp_free(conn->ctx, scram_init);
xmpp_stanza_release(auth);
disconnect_mem_error(conn);
return;
}
authdata = xmpp_stanza_new(conn->ctx);
if (!authdata) {
xmpp_free(conn->ctx, str);
xmpp_free(conn->ctx, scram_init);
xmpp_stanza_release(auth);
disconnect_mem_error(conn);
return;
}
xmpp_stanza_set_text(authdata, str);
xmpp_free(conn->ctx, str);
xmpp_stanza_add_child(auth, authdata);
xmpp_stanza_release(authdata);
handler_add(conn, _handle_scram_sha1_challenge,
XMPP_NS_SASL, NULL, NULL, (void *)scram_init);
xmpp_send(conn, auth);
xmpp_stanza_release(auth);
/* SASL SCRAM-SHA-1 was tried, unset flag */
conn->sasl_support &= ~SASL_MASK_SCRAMSHA1;
} else if (conn->sasl_support & SASL_MASK_DIGESTMD5) {
auth = _make_sasl_auth(conn, "DIGEST-MD5");
if (!auth) {

View File

@@ -21,12 +21,10 @@
#include <stdio.h>
#include <stdarg.h>
#ifndef _WIN32
#include <stdint.h>
#endif
#include "strophe.h"
#include "ostypes.h"
#include "sock.h"
#include "tls.h"
#include "hash.h"
@@ -147,6 +145,7 @@ struct _xmpp_handlist_t {
#define SASL_MASK_PLAIN 0x01
#define SASL_MASK_DIGESTMD5 0x02
#define SASL_MASK_ANONYMOUS 0x04
#define SASL_MASK_SCRAMSHA1 0x08
typedef void (*xmpp_open_handler)(xmpp_conn_t * const conn);

View File

@@ -270,7 +270,7 @@ int xmpp_conn_release(xmpp_conn_t * const conn)
if (conn->domain) xmpp_free(ctx, conn->domain);
if (conn->jid) xmpp_free(ctx, conn->jid);
if (conn->bound_jid) xmpp_free(ctx, conn->bound_jid);
if (conn->bound_jid) xmpp_free(ctx, conn->bound_jid);
if (conn->pass) xmpp_free(ctx, conn->pass);
if (conn->stream_id) xmpp_free(ctx, conn->stream_id);
if (conn->lang) xmpp_free(ctx, conn->lang);

View File

@@ -252,29 +252,34 @@ void xmpp_log(const xmpp_ctx_t * const ctx,
char *buf;
va_list copy;
buf = smbuf;
va_copy(copy, ap);
ret = xmpp_vsnprintf(buf, 1023, fmt, ap);
if (ret > 1023) {
ret = xmpp_vsnprintf(smbuf, sizeof(smbuf), fmt, ap);
if (ret >= (int)sizeof(smbuf)) {
buf = (char *)xmpp_alloc(ctx, ret + 1);
if (!buf) {
buf = NULL;
xmpp_error(ctx, "log", "Failed allocating memory for log message.");
va_end(copy);
va_end(copy);
return;
}
oldret = ret;
ret = xmpp_vsnprintf(buf, ret + 1, fmt, copy);
if (ret > oldret) {
xmpp_error(ctx, "log", "Unexpected error");
xmpp_free(ctx, buf);
va_end(copy);
return;
}
} else {
va_end(copy);
buf = smbuf;
}
va_end(copy);
if (ctx->log->handler)
ctx->log->handler(ctx->log->userdata, level, area, buf);
if (buf != smbuf)
xmpp_free(ctx, buf);
}
/** Write to the log at the ERROR level.

View File

@@ -23,14 +23,9 @@
#include <stdlib.h>
#include <string.h>
#ifndef _WIN32
#include <stdint.h>
#else
#include "ostypes.h"
#endif
#include "strophe.h"
#include "common.h"
#include "ostypes.h"
/** Fire off all stanza handlers that match.
* This function is called internally by the event loop whenever stanzas

View File

@@ -43,6 +43,9 @@
(cp)[3] = ((value) >> 24) & 0xFF; \
} while(0)
static void MD5Transform(uint32_t buf[4], const unsigned char inext[64],
struct MD5Context *ctx);
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
@@ -179,8 +182,8 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void MD5Transform(uint32_t buf[4], const unsigned char inext[64],
struct MD5Context *ctx)
static void MD5Transform(uint32_t buf[4], const unsigned char inext[64],
struct MD5Context *ctx)
{
register uint32_t a, b, c, d, i;
uint32_t in[16];

View File

@@ -11,15 +11,8 @@
#ifndef MD5_H
#define MD5_H
/* we use the uint32_t type from stdint.h
* if it is not available, add a typedef here:
*/
/* make sure the stdint.h types are available */
#if defined(_MSC_VER) /* Microsoft Visual C++ */
typedef unsigned int uint32_t;
#else
#include <stdint.h>
#endif
#include "ostypes.h"
struct MD5Context {
uint32_t buf[4];
@@ -31,8 +24,6 @@ void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, unsigned char const *buf,
uint32_t len);
void MD5Final(unsigned char digest[16], struct MD5Context *context);
void MD5Transform(uint32_t buf[4], const unsigned char in[64],
struct MD5Context *ctx);
#ifdef DEBUG_MD5
void MD5DumpBytes(unsigned char *b, int len);

View File

@@ -20,8 +20,18 @@
#ifndef __LIBSTROPHE_OSTYPES_H__
#define __LIBSTROPHE_OSTYPES_H__
#ifdef _WIN32
#if defined (_MSC_VER) && _MSC_VER < 1600
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef __int64 int64_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif /* __LIBSTROPHE_OSTYPES_H__ */

View File

@@ -16,26 +16,19 @@
* SASL authentication.
*/
#include <stdlib.h>
#include <string.h>
#include "strophe.h"
#include "common.h"
#include "ostypes.h"
#include "sasl.h"
#include "md5.h"
#include "sha1.h"
#include "scram.h"
/* make sure the stdint.h types are available */
#if defined(_MSC_VER) /* Microsoft Visual C++ */
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef __int64 int64_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
/* no uint64_t */
#else
#include <stdint.h>
#ifdef _WIN32
#define strtok_r strtok_s
#endif
@@ -360,6 +353,113 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
return response;
}
/** generate auth response string for the SASL SCRAM-SHA-1 mechanism */
char *sasl_scram_sha1(xmpp_ctx_t *ctx, const char *challenge,
const char *first_bare, const char *jid,
const char *password)
{
uint8_t key[SHA1_DIGEST_SIZE];
uint8_t sign[SHA1_DIGEST_SIZE];
char *r = NULL;
char *s = NULL;
char *i = NULL;
char *sval;
size_t sval_len;
long ival;
char *tmp;
char *ptr;
char *saveptr = NULL;
char *response;
char *auth;
char *response_b64;
char *sign_b64;
char *result = NULL;
size_t response_len;
size_t auth_len;
int j;
tmp = xmpp_strdup(ctx, challenge);
if (!tmp) {
return NULL;
}
ptr = strtok_r(tmp, ",", &saveptr);
while (ptr) {
if (strncmp(ptr, "r=", 2) == 0) {
r = ptr;
} else if (strncmp(ptr, "s=", 2) == 0) {
s = ptr + 2;
} else if (strncmp(ptr, "i=", 2) == 0) {
i = ptr + 2;
}
ptr = strtok_r(NULL, ",", &saveptr);
}
if (!r || !s || !i) {
goto out;
}
sval = (char *)base64_decode(ctx, s, strlen(s));
if (!sval) {
goto out;
}
sval_len = base64_decoded_len(ctx, s, strlen(s));
ival = strtol(i, &saveptr, 10);
auth_len = 10 + strlen(r) + strlen(first_bare) + strlen(challenge);
auth = xmpp_alloc(ctx, auth_len);
if (!auth) {
goto out_sval;
}
response_len = 39 + strlen(r);
response = xmpp_alloc(ctx, response_len);
if (!response) {
goto out_auth;
}
xmpp_snprintf(response, response_len, "c=biws,%s", r);
xmpp_snprintf(auth, auth_len, "%s,%s,%s", first_bare + 3, challenge,
response);
SCRAM_SHA1_ClientKey((uint8_t *)password, strlen(password),
(uint8_t *)sval, sval_len, (uint32_t)ival, key);
SCRAM_SHA1_ClientSignature(key, (uint8_t *)auth, strlen(auth), sign);
for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
sign[j] ^= key[j];
}
sign_b64 = base64_encode(ctx, sign, sizeof(sign));
if (!sign_b64) {
goto out_response;
}
if (strlen(response) + strlen(sign_b64) + 3 + 1 > response_len) {
xmpp_free(ctx, sign_b64);
goto out_response;
}
strcat(response, ",p=");
strcat(response, sign_b64);
xmpp_free(ctx, sign_b64);
response_b64 = base64_encode(ctx, (unsigned char *)response,
strlen(response));
if (!response_b64) {
goto out_response;
}
result = response_b64;
out_response:
xmpp_free(ctx, response);
out_auth:
xmpp_free(ctx, auth);
out_sval:
xmpp_free(ctx, sval);
out:
xmpp_free(ctx, tmp);
return result;
}
/** Base64 encoding routines. Implemented according to RFC 3548 */
@@ -552,8 +652,8 @@ unsigned char *base64_decode(xmpp_ctx_t *ctx,
if (hextet != 64) goto _base64_decode_error;
break;
}
*d = '\0';
}
*d = '\0';
return dbuf;
_base64_decode_error:

View File

@@ -26,6 +26,9 @@
char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password);
char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
const char *jid, const char *password);
char *sasl_scram_sha1(xmpp_ctx_t *ctx, const char *challenge,
const char *first_bare, const char *jid,
const char *password);
/** Base64 encoding routines. Implemented according to RFC 3548 */

146
src/scram.c Normal file
View File

@@ -0,0 +1,146 @@
/* scram.c
* strophe XMPP client library
*
* SCRAM-SHA1 helper functions according to RFC5802
* HMAC-SHA1 implementation according to RFC2104
*
* Copyright (C) 2013 Dmitry Podgorny <pasis.ua@gmail.com>
*
* This software is provided AS-IS with no warranty, either express
* or implied.
*
* This software is distributed under license and may not be copied,
* modified or distributed except as expressly authorized under the
* terms of the license contained in the file LICENSE.txt in this
* distribution.
*/
/** @file
* SCRAM-SHA1 helper functions.
*/
#include <assert.h>
#include <string.h>
#include "sha1.h"
#include "ostypes.h"
#include "scram.h"
/* block size for HMAC */
#define BLOCK_SIZE 64
#if BLOCK_SIZE < SHA1_DIGEST_SIZE
#error BLOCK_SIZE must not be less than SHA1_DIGEST_SIZE
#endif
static const uint8_t ipad = 0x36;
static const uint8_t opad = 0x5C;
static void SHA1(const uint8_t* data, size_t len,
uint8_t digest[SHA1_DIGEST_SIZE])
{
SHA1_CTX ctx;
SHA1_Init(&ctx);
SHA1_Update(&ctx, data, len);
SHA1_Final(&ctx, digest);
}
static void HMAC_SHA1(const uint8_t *key, size_t key_len,
const uint8_t *text, size_t len,
uint8_t digest[SHA1_DIGEST_SIZE])
{
uint8_t key_pad[BLOCK_SIZE];
uint8_t key_ipad[BLOCK_SIZE];
uint8_t key_opad[BLOCK_SIZE];
uint8_t sha_digest[SHA1_DIGEST_SIZE];
int i;
SHA1_CTX ctx;
memset(key_pad, 0, sizeof(key_pad));
if (key_len <= BLOCK_SIZE) {
memcpy(key_pad, key, key_len);
} else {
/* according to RFC2104 */
SHA1(key, key_len, key_pad);
}
for (i = 0; i < BLOCK_SIZE; i++) {
key_ipad[i] = key_pad[i] ^ ipad;
key_opad[i] = key_pad[i] ^ opad;
}
SHA1_Init(&ctx);
SHA1_Update(&ctx, key_ipad, BLOCK_SIZE);
SHA1_Update(&ctx, text, len);
SHA1_Final(&ctx, sha_digest);
SHA1_Init(&ctx);
SHA1_Update(&ctx, key_opad, BLOCK_SIZE);
SHA1_Update(&ctx, sha_digest, SHA1_DIGEST_SIZE);
SHA1_Final(&ctx, digest);
}
static void SCRAM_SHA1_Hi(const uint8_t *text, size_t len,
const uint8_t *salt, size_t salt_len, uint32_t i,
uint8_t digest[SHA1_DIGEST_SIZE])
{
int j, k;
uint8_t tmp[128];
static uint8_t int1[] = {0x0, 0x0, 0x0, 0x1};
/* assume salt + INT(1) isn't longer than sizeof(tmp) */
assert(salt_len <= sizeof(tmp) - sizeof(int1));
memset(digest, 0, SHA1_DIGEST_SIZE);
if (i == 0) {
return;
}
memcpy(tmp, salt, salt_len);
memcpy(&tmp[salt_len], int1, sizeof(int1));
/* 'text' for Hi is a 'key' for HMAC */
HMAC_SHA1(text, len, tmp, salt_len + sizeof(int1), digest);
memcpy(tmp, digest, SHA1_DIGEST_SIZE);
for (j = 1; j < i; j++) {
HMAC_SHA1(text, len, tmp, SHA1_DIGEST_SIZE, tmp);
for (k = 0; k < SHA1_DIGEST_SIZE; k++) {
digest[k] ^= tmp[k];
}
}
}
void SCRAM_SHA1_ClientKey(const uint8_t *password, size_t len,
const uint8_t *salt, size_t salt_len, uint32_t i,
uint8_t key[SHA1_DIGEST_SIZE])
{
uint8_t salted[SHA1_DIGEST_SIZE];
/* XXX: Normalize(password) is omitted */
SCRAM_SHA1_Hi(password, len, salt, salt_len, i, salted);
HMAC_SHA1(salted, SHA1_DIGEST_SIZE, (uint8_t *)"Client Key",
strlen("Client Key"), key);
}
void SCRAM_SHA1_ClientSignature(const uint8_t ClientKey[SHA1_DIGEST_SIZE],
const uint8_t *AuthMessage, size_t len,
uint8_t sign[SHA1_DIGEST_SIZE])
{
uint8_t stored[SHA1_DIGEST_SIZE];
SHA1(ClientKey, SHA1_DIGEST_SIZE, stored);
HMAC_SHA1(stored, SHA1_DIGEST_SIZE, AuthMessage, len, sign);
}
void SCRAM_SHA1_ClientProof(const uint8_t ClientKey[SHA1_DIGEST_SIZE],
const uint8_t ClientSignature[SHA1_DIGEST_SIZE],
uint8_t proof[SHA1_DIGEST_SIZE])
{
int i;
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
proof[i] = ClientKey[i] ^ ClientSignature[i];
}
}

39
src/scram.h Normal file
View File

@@ -0,0 +1,39 @@
/* scram.h
* strophe XMPP client library -- SCRAM-SHA1 helper functions
*
* Copyright (C) 2013 Dmitry Podgorny <pasis.ua@gmail.com>
*
* This software is provided AS-IS with no warranty, either express
* or implied.
*
* This software is distributed under license and may not be copied,
* modified or distributed except as expressly authorized under the
* terms of the license contained in the file LICENSE.txt in this
* distribution.
*/
/** @file
* SCRAM-SHA1 helper functions.
*/
#ifndef __LIBSTROPHE_SCRAM_H__
#define __LIBSTROPHE_SCRAM_H__
/* make sure the stdint.h types are available */
#include "ostypes.h"
#include "sha1.h"
void SCRAM_SHA1_ClientKey(const uint8_t *password, size_t len,
const uint8_t *salt, size_t salt_len, uint32_t i,
uint8_t key[SHA1_DIGEST_SIZE]);
void SCRAM_SHA1_ClientSignature(const uint8_t ClientKey[SHA1_DIGEST_SIZE],
const uint8_t *AuthMessage, size_t len,
uint8_t sign[SHA1_DIGEST_SIZE]);
void SCRAM_SHA1_ClientProof(const uint8_t ClientKey[SHA1_DIGEST_SIZE],
const uint8_t ClientSignature[SHA1_DIGEST_SIZE],
uint8_t proof[SHA1_DIGEST_SIZE]);
#endif /* __LIBSTROPHE_SCRAM_H__ */

View File

@@ -86,23 +86,11 @@ A million repetitions of "a"
#include <string.h>
/* make sure the stdint.h types are available */
#if defined(_MSC_VER) /* Microsoft Visual C++ */
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef __int64 int64_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
/* no uint64_t */
#else
#include <stdint.h>
#endif
#include "ostypes.h"
#include "sha1.h"
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
@@ -140,7 +128,7 @@ void SHAPrintContext(SHA1_CTX *context, char *msg){
#endif /* VERBOSE */
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
{
uint32_t a, b, c, d, e;
typedef union {

View File

@@ -12,6 +12,9 @@
extern "C" {
#endif
/* make sure the stdint.h types are available */
#include "ostypes.h"
typedef struct {
uint32_t state[5];
uint32_t count[2];

View File

@@ -25,7 +25,6 @@
#endif
#include <openssl/ssl.h>
#include <openssl/rand.h>
#include "common.h"
#include "tls.h"

View File

@@ -75,11 +75,11 @@ tls_t *tls_new(xmpp_ctx_t *ctx, sock_t sock)
SecPkgCred_CipherStrengths spc_cs;
SecPkgCred_SupportedProtocols spc_sp;
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
/* no TLS support on win9x/me, despite what anyone says */
@@ -102,7 +102,7 @@ tls_t *tls_new(xmpp_ctx_t *ctx, sock_t sock)
return NULL;
}
if (!(pInitSecurityInterface =
if (!(pInitSecurityInterface =
(void *)GetProcAddress(tls->hsec32, "InitSecurityInterfaceA"))) {
tls_free(tls);
return NULL;
@@ -148,26 +148,26 @@ tls_t *tls_new(xmpp_ctx_t *ctx, sock_t sock)
/* This bunch of queries should trip up wine until someone fixes
* schannel support there */
ret = tls->sft->QueryCredentialsAttributes(&(tls->hcred), SECPKG_ATTR_SUPPORTED_ALGS, &spc_sa);
if (ret != SEC_E_OK)
{
tls_free(tls);
return NULL;
}
ret = tls->sft->QueryCredentialsAttributes(&(tls->hcred), SECPKG_ATTR_CIPHER_STRENGTHS, &spc_cs);
if (ret != SEC_E_OK)
{
tls_free(tls);
return NULL;
}
ret = tls->sft->QueryCredentialsAttributes(&(tls->hcred), SECPKG_ATTR_SUPPORTED_PROTOCOLS, &spc_sp);
if (ret != SEC_E_OK)
{
tls_free(tls);
return NULL;
}
ret = tls->sft->QueryCredentialsAttributes(&(tls->hcred), SECPKG_ATTR_SUPPORTED_ALGS, &spc_sa);
if (ret != SEC_E_OK)
{
tls_free(tls);
return NULL;
}
ret = tls->sft->QueryCredentialsAttributes(&(tls->hcred), SECPKG_ATTR_CIPHER_STRENGTHS, &spc_cs);
if (ret != SEC_E_OK)
{
tls_free(tls);
return NULL;
}
ret = tls->sft->QueryCredentialsAttributes(&(tls->hcred), SECPKG_ATTR_SUPPORTED_PROTOCOLS, &spc_sp);
if (ret != SEC_E_OK)
{
tls_free(tls);
return NULL;
}
return tls;
}
@@ -196,7 +196,7 @@ void tls_free(tls_t *tls)
FreeLibrary(tls->hsec32);
tls->hsec32 = NULL;
}
xmpp_free(tls->ctx, tls);
return;
}
@@ -360,7 +360,7 @@ int tls_start(tls_t *tls)
return 0;
}
tls->sft->QueryContextAttributes(&(tls->hctxt), SECPKG_ATTR_STREAM_SIZES,
tls->sft->QueryContextAttributes(&(tls->hctxt), SECPKG_ATTR_STREAM_SIZES,
&(tls->spcss));
tls->recvbuffermaxlen = tls->spcss.cbHeader + tls->spcss.cbMaximumMessage
@@ -401,7 +401,7 @@ int tls_is_recoverable(int error)
int tls_pending(tls_t *tls) {
// There are 3 cases:
// - there is data in ready buffer, so it is by default pending
// - there is data in recv buffer. If it is not decrypted yet, means it
// - there is data in recv buffer. If it is not decrypted yet, means it
// was incomplete. This should be processed again only if there is data
// on the physical connection
// - there is data on the physical connection. This case is treated
@@ -440,7 +440,7 @@ int tls_read(tls_t *tls, void * const buff, const size_t len)
read = tls_read(tls, newbuff, len - bytes);
if (read == -1) {
if (tls_is_recoverable(tls->lasterror)) {
if (tls_is_recoverable(tls->lasterror)) {
return bytes;
}
@@ -454,11 +454,11 @@ int tls_read(tls_t *tls, void * const buff, const size_t len)
/* next, top up our recv buffer */
bytes = sock_read(tls->sock, tls->recvbuffer + tls->recvbufferpos,
tls->recvbuffermaxlen - tls->recvbufferpos);
if (bytes == 0) {
tls->lasterror = WSAECONNRESET;
return -1;
}
}
if (bytes == -1) {
if (!tls_is_recoverable(sock_error())) {
@@ -499,7 +499,7 @@ int tls_read(tls_t *tls, void * const buff, const size_t len)
ret = tls->sft->DecryptMessage(&(tls->hctxt), &sbddec, 0, NULL);
if (ret == SEC_E_OK) {
memcpy(tls->readybuffer, sbdec[1].pvBuffer, sbdec[1].cbBuffer);
memcpy(tls->readybuffer, sbdec[1].pvBuffer, sbdec[1].cbBuffer);
tls->readybufferpos = 0;
tls->readybufferlen = sbdec[1].cbBuffer;
/* have we got some data left over? If so, copy it to the start
@@ -631,8 +631,8 @@ int tls_write(tls_t *tls, const void * const buff, const size_t len)
if (ret == -1 && !tls_is_recoverable(tls_error(tls))) {
return -1;
}
}
if (remain > tls->spcss.cbMaximumMessage) {
sent += tls->spcss.cbMaximumMessage;
remain -= tls->spcss.cbMaximumMessage;

View File

@@ -24,11 +24,11 @@
#else
#include <sys/time.h>
#include <time.h>
#include <stdint.h>
#endif
#include "strophe.h"
#include "common.h"
#include "ostypes.h"
#include "util.h"
/** implement our own strdup that uses the ctx allocator */

View File

@@ -19,11 +19,7 @@
#ifndef __LIBSTROPHE_UTIL_H__
#define __LIBSTROPHE_UTIL_H__
#ifndef _WIN32
#include <stdint.h>
#else
#include "ostypes.h"
#endif
/* timing functions */
uint64_t time_stamp(void);