LA_CHECK_INCLUDE_FILE("bcrypt.h" HAVE_BCRYPT_H)
IF(HAVE_BCRYPT_H)
LIST(APPEND ADDITIONAL_LIBS "bcrypt")
+ # bcrypt supports these algorithms on all available versions
+ SET(ARCHIVE_CRYPTO_MD5 1)
+ SET(ARCHIVE_CRYPTO_MD5_WIN 1)
+ SET(ARCHIVE_CRYPTO_SHA1 1)
+ SET(ARCHIVE_CRYPTO_SHA1_WIN 1)
+ SET(ARCHIVE_CRYPTO_SHA256 1)
+ SET(ARCHIVE_CRYPTO_SHA256_WIN 1)
+ SET(ARCHIVE_CRYPTO_SHA384 1)
+ SET(ARCHIVE_CRYPTO_SHA384_WIN 1)
+ SET(ARCHIVE_CRYPTO_SHA512 1)
+ SET(ARCHIVE_CRYPTO_SHA512_WIN 1)
ENDIF(HAVE_BCRYPT_H)
ELSE(ENABLE_CNG)
UNSET(HAVE_BCRYPT_H CACHE)
ENDIF(ENABLE_CNG)
# Following files need windows.h, so we should test it after windows.h test.
-LA_CHECK_INCLUDE_FILE("wincrypt.h" HAVE_WINCRYPT_H)
LA_CHECK_INCLUDE_FILE("winioctl.h" HAVE_WINIOCTL_H)
#
ENDFOREACH(ALGORITHM ${ALGORITHMS})
ENDMACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
-#
-# CRYPTO functions on Windows is defined at archive_windows.c, thus we do not
-# need the test what the functions can be mapped to archive_{crypto name}_init,
-# archive_{crypto name}_update and archive_{crypto name}_final.
-# The functions on Windows use CALG_{crypto name} macro to create a crypt object
-# and then we need to know what CALG_{crypto name} macros is available to show
-# ARCHIVE_CRYPTO_{crypto name}_WIN macros because Windows 2000 and earlier version
-# of Windows XP do not support SHA256, SHA384 and SHA512.
-#
-MACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
- IF(WIN32 AND NOT CYGWIN)
- FOREACH(CRYPTO ${CRYPTO_LIST})
- IF(NOT ARCHIVE_CRYPTO_${CRYPTO})
- IF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
- STRING(TOUPPER "${CRYPTO}" crypto)
- SET(ALGID "")
- IF ("${CRYPTO}" MATCHES "^MD5$")
- SET(ALGID "CALG_MD5")
- ENDIF ("${CRYPTO}" MATCHES "^MD5$")
- IF ("${CRYPTO}" MATCHES "^SHA1$")
- SET(ALGID "CALG_SHA1")
- ENDIF ("${CRYPTO}" MATCHES "^SHA1$")
- IF ("${CRYPTO}" MATCHES "^SHA256$")
- SET(ALGID "CALG_SHA_256")
- ENDIF ("${CRYPTO}" MATCHES "^SHA256$")
- IF ("${CRYPTO}" MATCHES "^SHA384$")
- SET(ALGID "CALG_SHA_384")
- ENDIF ("${CRYPTO}" MATCHES "^SHA384$")
- IF ("${CRYPTO}" MATCHES "^SHA512$")
- SET(ALGID "CALG_SHA_512")
- ENDIF ("${CRYPTO}" MATCHES "^SHA512$")
-
- CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h)
- FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h"
- CONFDEFS_H)
-
- SET(SOURCE "${CONFDEFS_H}
-
-#define ${crypto}_COMPILE_TEST
-#include <windows.h>
-#include <wincrypt.h>
-
-int
-main(int argc, char **argv)
-{
- return ${ALGID};
-}
-")
- SET(SOURCE_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_win.c")
-
- FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
- MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
-
- TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
- ${CMAKE_BINARY_DIR}
- ${SOURCE_FILE}
- CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive"
- OUTPUT_VARIABLE OUTPUT)
-
- IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
- MESSAGE(STATUS
- "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- found")
- SET(ARCHIVE_CRYPTO_${CRYPTO} 1)
- ELSE (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
- MESSAGE(STATUS
- "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- not found")
- FILE(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN failed with the following output:\n"
- "${OUTPUT}\n"
- "Source file was:\n${SOURCE}\n")
- ENDIF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
- ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
- ENDIF(NOT ARCHIVE_CRYPTO_${CRYPTO})
- ENDFOREACH(CRYPTO)
- ENDIF(WIN32 AND NOT CYGWIN)
-ENDMACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
-
#
# Find iconv
# POSIX defines the second arg as const char **
# Libmd has to be probed after OpenSSL.
CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA512" LIBMD)
-CHECK_CRYPTO_WIN("MD5;SHA1;SHA256;SHA384;SHA512")
-
# Check visibility annotations
SET(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fvisibility=hidden -Werror")
AC_CHECK_TYPE([suseconds_t])
AC_CHECK_HEADERS([windows.h])
# check windows.h first; the other headers require it.
-AC_CHECK_HEADERS([wincrypt.h winioctl.h],[],[],
+AC_CHECK_HEADERS([winioctl.h],[],[],
[[#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
/* Define to 1 if you have the <wctype.h> header file. */
#define HAVE_WCTYPE_H 1
-/* Define to 1 if you have the <wincrypt.h> header file. */
-#define HAVE_WINCRYPT_H 1
-
/* Define to 1 if you have the <windows.h> header file. */
#define HAVE_WINDOWS_H 1
__LA_DECL const char * archive_libmd_version(void);
__LA_DECL const char * archive_commoncrypto_version(void);
__LA_DECL const char * archive_cng_version(void);
+#if ARCHIVE_VERSION_NUMBER < 4000000
__LA_DECL const char * archive_wincrypt_version(void);
+#endif
__LA_DECL const char * archive_librichacl_version(void);
__LA_DECL const char * archive_libacl_version(void);
__LA_DECL const char * archive_libattr_version(void);
return 0;
}
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
#ifdef _MSC_VER
#pragma comment(lib, "Bcrypt.lib")
#endif
return 0;
}
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
static int
aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
unsigned encr_pos;
} archive_crypto_ctx;
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
#include <bcrypt.h>
#define ARCHIVE_CRYPTOR_USE_CNG 1
#else
-#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA512_WIN)
-#if defined(_WIN32) && !defined(__CYGWIN__) && !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
-#define ARCHIVE_CRYPTOR_USE_WINCRYPT 1
-#endif
-#endif
-
#define AES_BLOCK_SIZE 16
#define AES_MAX_KEY_SIZE 32
typedef int archive_crypto_ctx;
/*
* Message digest functions for Windows platform.
*/
-#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
- defined(ARCHIVE_CRYPTO_SHA512_WIN)
+#if defined(HAVE_BCRYPT_H)
/*
* Initialize a Message digest.
*/
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
static int
win_crypto_init(Digest_CTX *ctx, const WCHAR *algo)
{
ctx->valid = 1;
return (ARCHIVE_OK);
}
-#else
-static int
-win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
-{
-
- ctx->valid = 0;
- if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- prov, CRYPT_VERIFYCONTEXT)) {
- if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
- return (ARCHIVE_FAILED);
- if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- prov, CRYPT_NEWKEYSET))
- return (ARCHIVE_FAILED);
- }
-
- if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) {
- CryptReleaseContext(ctx->cryptProv, 0);
- return (ARCHIVE_FAILED);
- }
-
- ctx->valid = 1;
- return (ARCHIVE_OK);
-}
-#endif
/*
* Update a Message digest.
if (!ctx->valid)
return (ARCHIVE_FAILED);
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
BCryptHashData(ctx->hHash,
(PUCHAR)(uintptr_t)buf,
(ULONG)len, 0);
-#else
- CryptHashData(ctx->hash,
- (unsigned char *)(uintptr_t)buf,
- (DWORD)len, 0);
-#endif
return (ARCHIVE_OK);
}
static int
win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
{
-#if !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA)
- DWORD siglen = (DWORD)bufsize;
-#endif
-
if (!ctx->valid)
return (ARCHIVE_FAILED);
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
BCryptFinishHash(ctx->hHash, buf, (ULONG)bufsize, 0);
BCryptDestroyHash(ctx->hHash);
BCryptCloseAlgorithmProvider(ctx->hAlg, 0);
-#else
- CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
- CryptDestroyHash(ctx->hash);
- CryptReleaseContext(ctx->cryptProv, 0);
-#endif
ctx->valid = 0;
return (ARCHIVE_OK);
}
-#endif /* defined(ARCHIVE_CRYPTO_*_WIN) */
+#endif /* defined(HAVE_BCRYPT_H) */
/* MD5 implementations */
static int
__archive_md5init(archive_md5_ctx *ctx)
{
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM));
-#else
- return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
-#endif
}
static int
static int
__archive_sha1init(archive_sha1_ctx *ctx)
{
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM));
-#else
- return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
-#endif
}
static int
static int
__archive_sha256init(archive_sha256_ctx *ctx)
{
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM));
-#else
- return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
-#endif
}
static int
static int
__archive_sha384init(archive_sha384_ctx *ctx)
{
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM));
-#else
- return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
-#endif
}
static int
static int
__archive_sha512init(archive_sha512_ctx *ctx)
{
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM));
-#else
- return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
-#endif
}
static int
defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\
defined(ARCHIVE_CRYPTO_SHA512_WIN)
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
-/* don't use bcrypt when XP needs to be supported */
+#if defined(HAVE_BCRYPT_H)
#include <bcrypt.h>
#define ARCHIVE_CRYPTO_CNG 1
typedef struct {
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_HASH_HANDLE hHash;
} Digest_CTX;
-#else
-#include <windows.h>
-#include <wincrypt.h>
-#define ARCHIVE_CRYPTO_WINCRYPT 1
-typedef struct {
- int valid;
- HCRYPTPROV cryptProv;
- HCRYPTHASH hash;
-} Digest_CTX;
#endif
#endif
memset(ctx, 0, sizeof(*ctx));
}
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
#ifndef BCRYPT_HASH_REUSABLE_FLAG
# define BCRYPT_HASH_REUSABLE_FLAG 0x00000020
typedef CCHmacContext archive_hmac_sha1_ctx;
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
#include <bcrypt.h>
typedef struct {
#include "archive.h"
#include "archive_random_private.h"
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
-/* don't use bcrypt when XP needs to be supported */
+#if defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H)
#include <bcrypt.h>
/* Common in other bcrypt implementations, but missing from VS2008. */
#ifndef BCRYPT_SUCCESS
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
#endif
-
-#elif defined(HAVE_WINCRYPT_H)
-#include <wincrypt.h>
-#endif
#endif
#ifndef O_CLOEXEC
archive_random(void *buf, size_t nbytes)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
-# if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
NTSTATUS status;
BCRYPT_ALG_HANDLE hAlg;
return ARCHIVE_FAILED;
return ARCHIVE_OK;
-# else
- HCRYPTPROV hProv;
- BOOL success;
-
- success = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT);
- if (!success && GetLastError() == (DWORD)NTE_BAD_KEYSET) {
- success = CryptAcquireContext(&hProv, NULL, NULL,
- PROV_RSA_FULL, CRYPT_NEWKEYSET);
- }
- if (success) {
- success = CryptGenRandom(hProv, (DWORD)nbytes, (BYTE*)buf);
- CryptReleaseContext(hProv, 0);
- if (success)
- return ARCHIVE_OK;
- }
- /* TODO: Does this case really happen? */
- return ARCHIVE_FAILED;
-# endif
#elif !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__))
la_arc4random_buf(buf, nbytes);
return ARCHIVE_OK;
#include <string.h>
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
-/* don't use bcrypt when XP needs to be supported */
+#if defined(HAVE_BCRYPT_H)
#include <bcrypt.h>
/* Common in other bcrypt implementations, but missing from VS2008. */
#ifndef BCRYPT_SUCCESS
#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
#endif
-
-#elif defined(HAVE_WINCRYPT_H)
-#include <wincrypt.h>
#endif
#endif
#ifdef HAVE_ZLIB_H
DWORD attr;
wchar_t *xp, *ep;
int fd;
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
BCRYPT_ALG_HANDLE hAlg = NULL;
-#else
- HCRYPTPROV hProv = (HCRYPTPROV)NULL;
-#endif
fd = -1;
ws = NULL;
archive_string_init(&temp_name);
abort();
}
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM,
NULL, 0))) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
-#else
- if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT)) {
- la_dosmaperr(GetLastError());
- goto exit_tmpfile;
- }
-#endif
for (;;) {
wchar_t *p;
/* Generate a random file name through CryptGenRandom(). */
p = xp;
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
if (!BCRYPT_SUCCESS(BCryptGenRandom(hAlg, (PUCHAR)p,
(DWORD)(ep - p)*sizeof(wchar_t), 0))) {
la_dosmaperr(GetLastError());
goto exit_tmpfile;
}
-#else
- if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
- (BYTE*)p)) {
- la_dosmaperr(GetLastError());
- goto exit_tmpfile;
- }
-#endif
for (; p < ep; p++)
*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
break;/* success! */
}
exit_tmpfile:
-#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
if (hAlg != NULL)
BCryptCloseAlgorithmProvider(hAlg, 0);
-#else
- if (hProv != (HCRYPTPROV)NULL)
- CryptReleaseContext(hProv, 0);
-#endif
free(ws);
if (template == temp_name.s)
archive_wstring_free(&temp_name);
#if defined(ARCHIVE_CRYPTOR_USE_LIBMD)
archive_strcat(str, " libmd/");
archive_strcat(str, archive_libmd_version());
-#endif
-#if defined(ARCHIVE_CRYPTOR_USE_WINCRYPT)
- archive_strcat(str, " WinCrypt/");
- archive_strcat(str, archive_wincrypt_version());
#endif
// Just in case
(void)str; /* UNUSED */
const char *
archive_wincrypt_version(void)
{
-#if defined(ARCHIVE_CRYPTOR_USE_WINCRYPT) || defined(ARCHIVE_CRYPTO_WINCRYPT)
- HCRYPTPROV prov;
- if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
- if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
- return NULL;
- if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
- return NULL;
- }
- DWORD version, length = sizeof(version);
- if (!CryptGetProvParam(prov, PP_VERSION, (BYTE *)&version, &length, 0)) {
- return NULL;
- } else {
- char major = (version >> 8) & 0xFF;
- char minor = version & 0xFF;
- static char wincrypt_version[6];
- snprintf(wincrypt_version, 6, "%hhd.%hhd", major, minor);
- return wincrypt_version;
- }
-#else
return NULL;
-#endif
}
const char *