#endif /* !WIN32 */
#include "collectd/network_buffer.h"
+#if WIN32
+# include "collectd/win_hmac.h"
+#endif
#define TYPE_HOST 0x0000
#define TYPE_TIME 0x0001
} /* }}} int nb_add_value_list */
/* TODO: Add encryption for Windows */
-#if HAVE_LIBGCRYPT
+#if WIN32
+static int nb_add_signature (lcc_network_buffer_t *nb) /* {{{ */
+{
+ BYTE *buffer;
+ DWORD buffer_size;
+
+ BYTE hash[32] = { 0 };
+ DWORD hash_size = sizeof (hash) / sizeof (hash[0]);
+
+ HCRYPTPROV hProv;
+ HCRYPTHASH hHash;
+ HCRYPTKEY hKey;
+ BOOL status;
+
+ /* The type, length and username have already been filled in by
+ * "lcc_network_buffer_initialize". All we do here is calculate the hash over
+ * the username and the data and add the hash value to the buffer. */
+ buffer = (LPBYTE) (nb->buffer + PART_SIGNATURE_SHA256_SIZE);
+ assert (nb->size >= (nb->free + PART_SIGNATURE_SHA256_SIZE));
+ buffer_size = (DWORD) (nb->size - (nb->free + PART_SIGNATURE_SHA256_SIZE));
+
+ status = CryptAcquireContext (&hProv,
+ /* szContainer = */ NULL,
+ /* CSP name = */ NULL,
+ /* provider type = */ PROV_RSA_AES,
+ /* flags = */ CRYPT_VERIFYCONTEXT);
+ if (!status)
+ return (-1);
+
+ status = CreateHMAC (hProv,
+ /* algorithm = */ CALG_SHA_256,
+ /* lpbKey = */ (LPBYTE) nb->password,
+ /* dwKeySize = */ (DWORD) strlen (nb->password),
+ /* dwFlags = */ 0,
+ /* lphHash = */ &hHash,
+ /* lphKey = */ &hKey);
+ if (!status)
+ {
+ CryptReleaseContext (hProv, /* dwFlags = */ 0);
+ return (-1);
+ }
+
+ status = CryptHashData (hHash,
+ /* pbData = */ buffer,
+ /* dwDataSize = */ buffer_size,
+ /* dwFlags = */ 0);
+ if (!status)
+ {
+ CryptDestroyHash (hHash);
+ CryptDestroyKey (hKey);
+ CryptReleaseContext (hProv, /* dwFlags = */ 0);
+ return (-1);
+ }
+
+ status = CryptGetHashParam (hHash,
+ /* dwParam = */ HP_HASHVAL,
+ /* pbData = */ hash,
+ /* pwdDataLen = */ &hash_size,
+ /* dwFlags = */ 0);
+ if (!status)
+ {
+ CryptDestroyHash (hHash);
+ CryptDestroyKey (hKey);
+ CryptReleaseContext (hProv, /* dwFlags = */ 0);
+ return (-1);
+ }
+
+ assert (((2 * sizeof (uint16_t)) + hash_size) == PART_SIGNATURE_SHA256_SIZE);
+ memcpy (nb->buffer + (2 * sizeof (uint16_t)), hash, hash_size);
+
+ CryptDestroyHash (hHash);
+ CryptDestroyKey (hKey);
+ CryptReleaseContext (hProv, /* dwFlags = */ 0);
+ return (0);
+} /* }}} int nb_add_signature */
+#elif HAVE_LIBGCRYPT
static int nb_add_signature (lcc_network_buffer_t *nb) /* {{{ */
{
char *buffer;
if (nb == NULL)
return (EINVAL);
-#if HAVE_LIBGCRYPT
+#if WIN32
+ if (nb->seclevel == SIGN)
+ nb_add_signature (nb);
+#elif HAVE_LIBGCRYPT
if (nb->seclevel == SIGN)
nb_add_signature (nb);
else if (nb->seclevel == ENCRYPT)