diff options
author | Marc Hoersken <info@marc-hoersken.de> | 2012-09-11 01:58:10 +0200 |
---|---|---|
committer | Marc Hoersken <info@marc-hoersken.de> | 2012-09-11 13:37:30 +0200 |
commit | 94c3e0f702c23c30e69c17bddd77c368d1eaac22 (patch) | |
tree | d7ae971c7187d4f3ba5ff3af2f66384ff190e7dc | |
parent | c8846c09079a564ed1f24714acbf52b398b9cce1 (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.
-rw-r--r-- | src/tool_metalink.c | 95 |
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[] = { |