diff --git a/ChangeLog b/ChangeLog index 0caf124..c2f9ee4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ 0.10.0 + - SCRAM-SHA-256 and SCRAM-SHA-512 support - c-ares support - LibreSSL support - examples/register implements XEP-0077 diff --git a/Makefile.am b/Makefile.am index 8a48730..aff4e5a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -38,6 +38,8 @@ libstrophe_la_SOURCES = \ src/sasl.c \ src/scram.c \ src/sha1.c \ + src/sha256.c \ + src/sha512.c \ src/snprintf.c \ src/sock.c \ src/stanza.c \ @@ -53,7 +55,10 @@ libstrophe_la_SOURCES += \ src/resolver.h \ src/sasl.h \ src/scram.h \ + src/sha.h \ src/sha1.h \ + src/sha256.h \ + src/sha512.h \ src/snprintf.h \ src/sock.h \ src/tls.h \ @@ -183,7 +188,8 @@ tests_test_resolver_LDFLAGS = -static tests_test_rand_SOURCES = tests/test_rand.c tests/test.c src/sha1.c tests_test_rand_CFLAGS = $(STROPHE_FLAGS) -I$(top_srcdir)/src -tests_test_scram_SOURCES = tests/test_scram.c tests/test.c src/sha1.c +tests_test_scram_SOURCES = tests/test_scram.c tests/test.c src/sha1.c \ + src/sha256.c src/sha512.c tests_test_scram_CFLAGS = $(STROPHE_FLAGS) -I$(top_srcdir)/src tests_test_sha1_SOURCES = tests/test_sha1.c src/sha1.c diff --git a/src/auth.c b/src/auth.c index 5954f65..badf469 100644 --- a/src/auth.c +++ b/src/auth.c @@ -250,6 +250,10 @@ static int _handle_features(xmpp_conn_t *const conn, conn->sasl_support |= SASL_MASK_DIGESTMD5; else if (strcasecmp(text, "SCRAM-SHA-1") == 0) conn->sasl_support |= SASL_MASK_SCRAMSHA1; + else if (strcasecmp(text, "SCRAM-SHA-256") == 0) + conn->sasl_support |= SASL_MASK_SCRAMSHA256; + else if (strcasecmp(text, "SCRAM-SHA-512") == 0) + conn->sasl_support |= SASL_MASK_SCRAMSHA512; else if (strcasecmp(text, "ANONYMOUS") == 0) conn->sasl_support |= SASL_MASK_ANONYMOUS; @@ -644,7 +648,12 @@ static void _auth(xmpp_conn_t *const conn) xmpp_disconnect(conn); } else if (conn->sasl_support & SASL_MASK_SCRAM) { scram_ctx = xmpp_alloc(conn->ctx, sizeof(*scram_ctx)); - scram_ctx->alg = &scram_sha1; + if (conn->sasl_support & SASL_MASK_SCRAMSHA512) + scram_ctx->alg = &scram_sha512; + else if (conn->sasl_support & SASL_MASK_SCRAMSHA256) + scram_ctx->alg = &scram_sha256; + else if (conn->sasl_support & SASL_MASK_SCRAMSHA1) + scram_ctx->alg = &scram_sha1; auth = _make_sasl_auth(conn, scram_ctx->alg->scram_name); if (!auth) { disconnect_mem_error(conn); diff --git a/src/common.h b/src/common.h index b9ae58c..0d43839 100644 --- a/src/common.h +++ b/src/common.h @@ -136,8 +136,11 @@ struct _xmpp_handlist_t { #define SASL_MASK_DIGESTMD5 (1 << 1) #define SASL_MASK_ANONYMOUS (1 << 2) #define SASL_MASK_SCRAMSHA1 (1 << 3) +#define SASL_MASK_SCRAMSHA256 (1 << 4) +#define SASL_MASK_SCRAMSHA512 (1 << 5) -#define SASL_MASK_SCRAM (SASL_MASK_SCRAMSHA1) +#define SASL_MASK_SCRAM \ + (SASL_MASK_SCRAMSHA1 | SASL_MASK_SCRAMSHA256 | SASL_MASK_SCRAMSHA512) enum { XMPP_PORT_CLIENT = 5222, diff --git a/src/scram.c b/src/scram.c index 541d8ee..7bcc21d 100644 --- a/src/scram.c +++ b/src/scram.c @@ -21,6 +21,8 @@ #include "common.h" #include "sha1.h" +#include "sha256.h" +#include "sha512.h" #include "ostypes.h" #include "scram.h" @@ -39,8 +41,28 @@ const struct hash_alg scram_sha1 = { (void (*)(void *, const uint8_t *, size_t))crypto_SHA1_Update, (void (*)(void *, uint8_t *))crypto_SHA1_Final}; +const struct hash_alg scram_sha256 = { + "SCRAM-SHA-256", + SASL_MASK_SCRAMSHA256, + SHA256_DIGEST_SIZE, + (void (*)(const uint8_t *, size_t, uint8_t *))sha256_hash, + (void (*)(void *))sha256_init, + (void (*)(void *, const uint8_t *, size_t))sha256_process, + (void (*)(void *, uint8_t *))sha256_done}; + +const struct hash_alg scram_sha512 = { + "SCRAM-SHA-512", + SASL_MASK_SCRAMSHA512, + SHA512_DIGEST_SIZE, + (void (*)(const uint8_t *, size_t, uint8_t *))sha512_hash, + (void (*)(void *))sha512_init, + (void (*)(void *, const uint8_t *, size_t))sha512_process, + (void (*)(void *, uint8_t *))sha512_done}; + union common_hash_ctx { SHA1_CTX sha1; + sha256_context sha256; + sha512_context sha512; }; static void crypto_HMAC(const struct hash_alg *alg, @@ -53,7 +75,7 @@ static void crypto_HMAC(const struct hash_alg *alg, uint8_t key_pad[HMAC_BLOCK_SIZE]; uint8_t key_ipad[HMAC_BLOCK_SIZE]; uint8_t key_opad[HMAC_BLOCK_SIZE]; - uint8_t sha_digest[SHA1_DIGEST_SIZE]; + uint8_t sha_digest[SHA512_DIGEST_SIZE]; int i; union common_hash_ctx ctx; @@ -126,7 +148,7 @@ void SCRAM_ClientKey(const struct hash_alg *alg, uint32_t i, uint8_t *key) { - uint8_t salted[SHA1_DIGEST_SIZE]; + uint8_t salted[SHA512_DIGEST_SIZE]; /* XXX: Normalize(password) is omitted */ @@ -141,7 +163,7 @@ void SCRAM_ClientSignature(const struct hash_alg *alg, size_t len, uint8_t *sign) { - uint8_t stored[SHA1_DIGEST_SIZE]; + uint8_t stored[SHA512_DIGEST_SIZE]; alg->hash(ClientKey, alg->digest_size, stored); crypto_HMAC(alg, stored, alg->digest_size, AuthMessage, len, sign); diff --git a/src/scram.h b/src/scram.h index f744ef8..a0049e0 100644 --- a/src/scram.h +++ b/src/scram.h @@ -30,6 +30,8 @@ struct hash_alg { }; extern const struct hash_alg scram_sha1; +extern const struct hash_alg scram_sha256; +extern const struct hash_alg scram_sha512; void SCRAM_ClientKey(const struct hash_alg *alg, const uint8_t *password,