summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordefanor <defanor@uberspace.net>2021-10-02 14:36:31 +0300
committerdefanor <defanor@uberspace.net>2021-10-02 14:36:31 +0300
commit43f40dd55fa9d20b6ff29e4eca45de88ef01a2d7 (patch)
tree1bdad06a9e43a29aa4a83ba4334442043a982261 /src
parent3af2e52b7b98d894fc5c74e674e95eac24b74f6b (diff)
Use libgcrypt for hashing and random
Libgsasl will probably be made optional, so another source of random is needed. Libgsasl uses libgcrypt underneath. Gcrypt, unlike nettle, handles random seeding on its own, which would be annoying to implement for different platforms otherwise.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/rexmpp.c38
-rw-r--r--src/rexmpp_jingle.c32
-rw-r--r--src/rexmpp_openpgp.c10
4 files changed, 46 insertions, 38 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index c4b5591..b77083c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,8 +28,8 @@ include_HEADERS = config.h rexmpp_roster.h rexmpp_tcp.h rexmpp_socks.h rexmpp.h
librexmpp_la_CFLAGS = $(AM_CFLAGS) $(LIBXML_CFLAGS) \
$(GNUTLS_CFLAGS) $(LIBDANE_CFLAGS) $(OPENSSL_CFLAGS) \
$(GSASL_CFLAGS) $(UNBOUND_CFLAGS) $(CARES_CFLAGS) $(GPGME_CFLAGS) \
- $(ICU_I18N_CFLAGS) $(NETTLE_CFLAGS) $(CURL_CFLAGS)
+ $(ICU_I18N_CFLAGS) $(LIBGCRYPT_CFLAGS) $(CURL_CFLAGS)
librexmpp_la_LIBADD = $(LIBXML_LIBS) \
$(GNUTLS_LIBS) $(LIBDANE_LIBS) $(OPENSSL_LIBS) \
$(GSASL_LIBS) $(UNBOUND_LIBS) $(CARES_LIBS) $(GPGME_LIBS) $(ICU_I18N_LIBS) \
- $(NETTLE_LIBS) $(CURL_LIBS)
+ $(LIBGCRYPT_LIBS) $(CURL_LIBS)
diff --git a/src/rexmpp.c b/src/rexmpp.c
index de01b2a..5d45f6e 100644
--- a/src/rexmpp.c
+++ b/src/rexmpp.c
@@ -17,7 +17,7 @@
#include "config.h"
-#include <nettle/sha1.h>
+#include <gcrypt.h>
#include <libxml/tree.h>
#include <libxml/xmlsave.h>
#include <gsasl.h>
@@ -216,15 +216,19 @@ char *rexmpp_capabilities_string (rexmpp_t *s, xmlNodePtr info) {
char *rexmpp_capabilities_hash (rexmpp_t *s,
xmlNodePtr info)
{
- struct sha1_ctx ctx;
- sha1_init(&ctx);
- char hash[SHA1_DIGEST_SIZE];
- char *str = rexmpp_capabilities_string(s, info);
- sha1_update(&ctx, strlen(str), str);
- sha1_digest(&ctx, SHA1_DIGEST_SIZE, hash);
char *out = NULL;
size_t out_len = 0;
- gsasl_base64_to(hash, SHA1_DIGEST_SIZE, &out, &out_len);
+ char *str = rexmpp_capabilities_string(s, info);
+ if (str != NULL) {
+ unsigned int sha1_len = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
+ char *sha1 = malloc(sha1_len);
+ if (sha1 != NULL) {
+ gcry_md_hash_buffer(GCRY_MD_SHA1, sha1, str, strlen(str));
+ gsasl_base64_to(sha1, sha1_len, &out, &out_len);
+ free(sha1);
+ }
+ free(str);
+ }
return out;
}
@@ -599,6 +603,15 @@ rexmpp_err_t rexmpp_init (rexmpp_t *s,
return REXMPP_E_JID;
}
+ if (! gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) {
+ rexmpp_log(s, LOG_DEBUG, "Initializing libgcrypt");
+ if (gcry_check_version(NULL) == NULL) {
+ rexmpp_log(s, LOG_CRIT, "Failed to initialize libgcrypt");
+ return REXMPP_E_OTHER;
+ }
+ gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
+ }
+
s->xml_parser = xmlCreatePushParserCtxt(&sax, s, "", 0, NULL);
if (s->xml_parser == NULL) {
@@ -790,7 +803,7 @@ void rexmpp_schedule_reconnect (rexmpp_t *s) {
return;
}
if (s->reconnect_number == 0) {
- gsasl_nonce((char*)&s->reconnect_seconds, sizeof(time_t));
+ gcry_create_nonce((char*)&s->reconnect_seconds, sizeof(time_t));
if (s->reconnect_seconds < 0) {
s->reconnect_seconds = - s->reconnect_seconds;
}
@@ -825,12 +838,7 @@ char *rexmpp_gen_id (rexmpp_t *s) {
int sasl_err;
char buf_raw[18], *buf_base64 = NULL;
size_t buf_base64_len = 0;
- sasl_err = gsasl_nonce(buf_raw, 18);
- if (sasl_err != GSASL_OK) {
- rexmpp_log(s, LOG_ERR, "Random generation failure: %s",
- gsasl_strerror(sasl_err));
- return NULL;
- }
+ gcry_create_nonce(buf_raw, 18);
sasl_err = gsasl_base64_to(buf_raw, 18, &buf_base64, &buf_base64_len);
if (sasl_err != GSASL_OK) {
rexmpp_log(s, LOG_ERR, "Base-64 encoding failure: %s",
diff --git a/src/rexmpp_jingle.c b/src/rexmpp_jingle.c
index 25cbdb4..1e0674c 100644
--- a/src/rexmpp_jingle.c
+++ b/src/rexmpp_jingle.c
@@ -17,8 +17,7 @@ The following XEPs are handled here so far:
#include <errno.h>
#include <libgen.h>
#include <gsasl.h>
-#include <nettle/sha2.h>
-#include <nettle/sha3.h>
+#include <gcrypt.h>
#include "rexmpp.h"
#include "rexmpp_jingle.h"
@@ -279,38 +278,43 @@ rexmpp_jingle_send_file (rexmpp_t *s,
char buf[4096];
- char hash_sha256[SHA256_DIGEST_SIZE];
- struct sha256_ctx sha2_ctx;
- sha256_init(&sha2_ctx);
- char hash_sha3_256[SHA3_256_DIGEST_SIZE];
- struct sha3_256_ctx sha3_ctx;
- sha3_256_init(&sha3_ctx);
+ gcry_md_hd_t hd;
+ /* todo: check for hashing errors */
+ gcry_md_open(&hd, GCRY_MD_SHA256, 0);
+ gcry_md_enable(hd, GCRY_MD_SHA3_256);
size_t len = fread(buf, 1, 4096, fh);
while (len > 0) {
- sha256_update(&sha2_ctx, len, buf);
- sha3_256_update(&sha3_ctx, len, buf);
+ gcry_md_write(hd, buf, len);
len = fread(buf, 1, 4096, fh);
}
- sha256_digest(&sha2_ctx, SHA256_DIGEST_SIZE, hash_sha256);
+ gcry_md_final(hd);
+
char *hash_base64 = NULL;
size_t hash_base64_len = 0;
- gsasl_base64_to(hash_sha256, SHA256_DIGEST_SIZE, &hash_base64, &hash_base64_len);
+ gsasl_base64_to(gcry_md_read(hd, GCRY_MD_SHA256),
+ gcry_md_get_algo_dlen(GCRY_MD_SHA256),
+ &hash_base64,
+ &hash_base64_len);
xmlNodePtr file_hash = rexmpp_xml_new_node("hash", "urn:xmpp:hashes:2");
xmlNewProp(file_hash, "algo", "sha-256");
xmlNodeAddContent(file_hash, hash_base64);
free(hash_base64);
xmlAddChild(file, file_hash);
- sha3_256_digest(&sha3_ctx, SHA3_256_DIGEST_SIZE, hash_sha3_256);
hash_base64 = NULL;
hash_base64_len = 0;
- gsasl_base64_to(hash_sha3_256, SHA3_256_DIGEST_SIZE, &hash_base64, &hash_base64_len);
+ gsasl_base64_to(gcry_md_read(hd, GCRY_MD_SHA3_256),
+ gcry_md_get_algo_dlen(GCRY_MD_SHA3_256),
+ &hash_base64,
+ &hash_base64_len);
file_hash = rexmpp_xml_new_node("hash", "urn:xmpp:hashes:2");
xmlNewProp(file_hash, "algo", "sha3-256");
xmlNodeAddContent(file_hash, hash_base64);
free(hash_base64);
xmlAddChild(file, file_hash);
+ gcry_md_close(hd);
+
long fsize = ftell(fh);
fseek(fh, 0, SEEK_SET);
snprintf(buf, 11, "%ld", fsize);
diff --git a/src/rexmpp_openpgp.c b/src/rexmpp_openpgp.c
index 3e71169..09b2b4e 100644
--- a/src/rexmpp_openpgp.c
+++ b/src/rexmpp_openpgp.c
@@ -48,6 +48,7 @@ Possible future improvements:
#include <gpgme.h>
#endif
#include <libxml/tree.h>
+#include <gcrypt.h>
#include <gsasl.h>
#include "rexmpp.h"
@@ -755,14 +756,9 @@ char *rexmpp_openpgp_payload (rexmpp_t *s,
/* A random-length random-content padding. */
char *rand_str, rand[256];
- gsasl_nonce(rand, 1);
+ gcry_create_nonce(rand, 1);
size_t rand_str_len = 0, rand_len = (unsigned char)rand[0] % (255 - 16) + 16;
- sasl_err = gsasl_nonce(rand, rand_len);
- if (sasl_err != GSASL_OK) {
- rexmpp_log(s, LOG_ERR, "Random generation failure: %s",
- gsasl_strerror(sasl_err));
- return NULL;
- }
+ gcry_create_nonce(rand, rand_len);
sasl_err = gsasl_base64_to(rand, rand_len, &rand_str, &rand_str_len);
if (sasl_err != GSASL_OK) {
rexmpp_log(s, LOG_ERR, "Base-64 encoding failure: %s",