aboutsummaryrefslogtreecommitdiff
path: root/src/tool_metalink.c
diff options
context:
space:
mode:
authorMarc Hoersken <info@marc-hoersken.de>2012-09-11 01:58:10 +0200
committerMarc Hoersken <info@marc-hoersken.de>2012-09-11 13:37:30 +0200
commit94c3e0f702c23c30e69c17bddd77c368d1eaac22 (patch)
treed7ae971c7187d4f3ba5ff3af2f66384ff190e7dc /src/tool_metalink.c
parentc8846c09079a564ed1f24714acbf52b398b9cce1 (diff)
tool_metalink.c: Added support for Microsoft Windows CryptoAPI
Since Metalink support requires a crypto library for hash functions and Windows comes with the builtin CryptoAPI, this patch adds that API as a fallback to the supported crypto libraries. It is automatically used on Windows if no other library is provided.
Diffstat (limited to 'src/tool_metalink.c')
-rw-r--r--src/tool_metalink.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/tool_metalink.c b/src/tool_metalink.c
index b9c291851..9199b50f7 100644
--- a/src/tool_metalink.c
+++ b/src/tool_metalink.c
@@ -61,6 +61,25 @@
and later. If you're building for an older cat, well, sorry. */
# define COMMON_DIGEST_FOR_OPENSSL
# include <CommonCrypto/CommonDigest.h>
+#elif defined(_WIN32)
+/* For Windows: If no other crypto library is provided, we fallback
+ to the hash functions provided within the Microsoft Windows CryptoAPI */
+# include <WinCrypt.h>
+/* Custom structure in order to store the required provider and hash handle */
+struct win32_crypto_hash {
+ HCRYPTPROV hCryptProv;
+ HCRYPTHASH hHash;
+};
+/* Custom Microsoft AES Cryptographic Provider defines required for MinGW */
+# ifndef ALG_SID_SHA_256
+# define ALG_SID_SHA_256 12
+# endif
+# ifndef CALG_SHA_256
+# define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256)
+# endif
+# define MD5_CTX struct win32_crypto_hash
+# define SHA_CTX struct win32_crypto_hash
+# define SHA256_CTX struct win32_crypto_hash
#else
# error "Can't compile METALINK support without a crypto library."
#endif
@@ -200,6 +219,82 @@ static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
gcry_md_close(*ctx);
}
+#elif defined(_WIN32)
+
+static void win32_crypto_final(struct win32_crypto_hash *ctx,
+ unsigned char *digest,
+ unsigned int digestLen)
+{
+ unsigned long length;
+ CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
+ if(length == digestLen)
+ CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
+ if(ctx->hHash)
+ CryptDestroyHash(ctx->hHash);
+ if(ctx->hCryptProv)
+ CryptReleaseContext(ctx->hCryptProv, 0);
+}
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+ if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+ CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
+ }
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+ const unsigned char *input,
+ unsigned int inputLen)
+{
+ CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+ win32_crypto_final(ctx, digest, 16);
+}
+
+static void SHA1_Init(SHA_CTX *ctx)
+{
+ if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+ CryptCreateHash(ctx->hCryptProv, CALG_SHA1, 0, 0, &ctx->hHash);
+ }
+}
+
+static void SHA1_Update(SHA_CTX *ctx,
+ const unsigned char *input,
+ unsigned int inputLen)
+{
+ CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
+}
+
+static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx)
+{
+ win32_crypto_final(ctx, digest, 20);
+}
+
+static void SHA256_Init(SHA256_CTX *ctx)
+{
+ if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
+ PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
+ CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
+ }
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+ const unsigned char *input,
+ unsigned int inputLen)
+{
+ CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
+}
+
+static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
+{
+ win32_crypto_final(ctx, digest, 32);
+}
+
#endif /* CRYPTO LIBS */
const digest_params MD5_DIGEST_PARAMS[] = {