mirror of https://github.com/aria2/aria2
WinTLS: Implement messsage digest using the Cryptography Provider
parent
b678bc5e10
commit
a4e29303ef
88
configure.ac
88
configure.ac
|
@ -40,6 +40,7 @@ AC_DEFINE_UNQUOTED([TARGET], ["$target"], [Define target-type])
|
||||||
# Checks for arguments.
|
# Checks for arguments.
|
||||||
ARIA2_ARG_WITHOUT([libuv])
|
ARIA2_ARG_WITHOUT([libuv])
|
||||||
ARIA2_ARG_WITHOUT([appletls])
|
ARIA2_ARG_WITHOUT([appletls])
|
||||||
|
ARIA2_ARG_WITHOUT([wintls])
|
||||||
ARIA2_ARG_WITHOUT([gnutls])
|
ARIA2_ARG_WITHOUT([gnutls])
|
||||||
ARIA2_ARG_WITHOUT([libnettle])
|
ARIA2_ARG_WITHOUT([libnettle])
|
||||||
ARIA2_ARG_WITHOUT([libgmp])
|
ARIA2_ARG_WITHOUT([libgmp])
|
||||||
|
@ -286,8 +287,30 @@ case "$host" in
|
||||||
*darwin*)
|
*darwin*)
|
||||||
have_osx="yes"
|
have_osx="yes"
|
||||||
;;
|
;;
|
||||||
|
*mingw*)
|
||||||
|
AC_CHECK_HEADERS([windows.h \
|
||||||
|
winsock2.h \
|
||||||
|
ws2tcpip.h \
|
||||||
|
mmsystem.h \
|
||||||
|
io.h \
|
||||||
|
iphlpapi.h\
|
||||||
|
winioctl.h \
|
||||||
|
share.h], [], [],
|
||||||
|
[[
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
# include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
# include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
]])
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
||||||
if test "x$with_appletls" = "xyes"; then
|
if test "x$with_appletls" = "xyes"; then
|
||||||
AC_MSG_CHECKING([whether to enable Mac OS X native SSL/TLS])
|
AC_MSG_CHECKING([whether to enable Mac OS X native SSL/TLS])
|
||||||
if test "x$have_osx" = "xyes"; then
|
if test "x$have_osx" = "xyes"; then
|
||||||
|
@ -303,6 +326,23 @@ if test "x$with_appletls" = "xyes"; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "x$with_wintls" = "xyes"; then
|
||||||
|
AC_SEARCH_LIBS([CryptAcquireContextW], [advapi32], [
|
||||||
|
AC_CHECK_HEADER([wincrypt.h], [have_wincrypt=yes], [have_wincrypt=no],
|
||||||
|
[[
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
]])
|
||||||
|
break;
|
||||||
|
], [have_wincrypt=no])
|
||||||
|
if test "x$have_wincrypt" != "xyes"; then
|
||||||
|
if test "x$with_wintls_requested" = "xyes"; then
|
||||||
|
ARIA2_DEP_NOT_MET([wintls])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if test "x$with_gnutls" = "xyes" && test "x$have_appletls" != "xyes"; then
|
if test "x$with_gnutls" = "xyes" && test "x$have_appletls" != "xyes"; then
|
||||||
# gnutls >= 2.8 doesn't have libgnutls-config anymore. We require
|
# gnutls >= 2.8 doesn't have libgnutls-config anymore. We require
|
||||||
# 2.2.0 because we use gnutls_priority_set_direct()
|
# 2.2.0 because we use gnutls_priority_set_direct()
|
||||||
|
@ -398,17 +438,22 @@ if test "x$have_osx" == "xyes"; then
|
||||||
use_md="apple"
|
use_md="apple"
|
||||||
AC_DEFINE([USE_APPLE_MD], [1], [What message digest implementation to use])
|
AC_DEFINE([USE_APPLE_MD], [1], [What message digest implementation to use])
|
||||||
else
|
else
|
||||||
if test "x$have_libnettle" = "xyes"; then
|
if test "x$have_wincrypt" == "xyes"; then
|
||||||
AC_DEFINE([USE_LIBNETTLE_MD], [1], [What message digest implementation to use])
|
use_md="windows"
|
||||||
use_md="libnettle"
|
AC_DEFINE([USE_WINDOWS_MD], [1], [What message digest implementation to use])
|
||||||
else
|
else
|
||||||
if test "x$have_libgcrypt" = "xyes"; then
|
if test "x$have_libnettle" = "xyes"; then
|
||||||
AC_DEFINE([USE_LIBGCRYPT_MD], [1], [What message digest implementation to use])
|
AC_DEFINE([USE_LIBNETTLE_MD], [1], [What message digest implementation to use])
|
||||||
use_md="libgcrypt"
|
use_md="libnettle"
|
||||||
else
|
else
|
||||||
if test "x$have_openssl" = "xyes"; then
|
if test "x$have_libgcrypt" = "xyes"; then
|
||||||
AC_DEFINE([USE_OPENSSL_MD], [1], [What message digest implementation to use])
|
AC_DEFINE([USE_LIBGCRYPT_MD], [1], [What message digest implementation to use])
|
||||||
use_md="openssl"
|
use_md="libgcrypt"
|
||||||
|
else
|
||||||
|
if test "x$have_openssl" = "xyes"; then
|
||||||
|
AC_DEFINE([USE_OPENSSL_MD], [1], [What message digest implementation to use])
|
||||||
|
use_md="openssl"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -427,6 +472,7 @@ fi
|
||||||
AM_CONDITIONAL([HAVE_OSX], [ test "x$have_osx" = "xyes" ])
|
AM_CONDITIONAL([HAVE_OSX], [ test "x$have_osx" = "xyes" ])
|
||||||
AM_CONDITIONAL([HAVE_APPLETLS], [ test "x$have_appletls" = "xyes" ])
|
AM_CONDITIONAL([HAVE_APPLETLS], [ test "x$have_appletls" = "xyes" ])
|
||||||
AM_CONDITIONAL([USE_APPLE_MD], [ test "x$use_md" = "xapple" ])
|
AM_CONDITIONAL([USE_APPLE_MD], [ test "x$use_md" = "xapple" ])
|
||||||
|
AM_CONDITIONAL([USE_WINDOWS_MD], [ test "x$use_md" = "xwindows" ])
|
||||||
AM_CONDITIONAL([HAVE_LIBGNUTLS], [ test "x$have_libgnutls" = "xyes" ])
|
AM_CONDITIONAL([HAVE_LIBGNUTLS], [ test "x$have_libgnutls" = "xyes" ])
|
||||||
AM_CONDITIONAL([HAVE_LIBNETTLE], [ test "x$have_libnettle" = "xyes" ])
|
AM_CONDITIONAL([HAVE_LIBNETTLE], [ test "x$have_libnettle" = "xyes" ])
|
||||||
AM_CONDITIONAL([USE_LIBNETTLE_MD], [ test "x$use_md" = "xlibnettle"])
|
AM_CONDITIONAL([USE_LIBNETTLE_MD], [ test "x$use_md" = "xlibnettle"])
|
||||||
|
@ -519,30 +565,6 @@ esac
|
||||||
AC_FUNC_ALLOCA
|
AC_FUNC_ALLOCA
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
|
|
||||||
case "$host" in
|
|
||||||
*mingw*)
|
|
||||||
AC_CHECK_HEADERS([windows.h \
|
|
||||||
winsock2.h \
|
|
||||||
ws2tcpip.h \
|
|
||||||
mmsystem.h \
|
|
||||||
io.h \
|
|
||||||
iphlpapi.h\
|
|
||||||
winioctl.h \
|
|
||||||
share.h], [], [],
|
|
||||||
[[
|
|
||||||
#ifdef HAVE_WS2TCPIP_H
|
|
||||||
# include <ws2tcpip.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WINSOCK2_H
|
|
||||||
# include <winsock2.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WINDOWS_H
|
|
||||||
# include <windows.h>
|
|
||||||
#endif
|
|
||||||
]])
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
AC_CHECK_HEADERS([argz.h \
|
AC_CHECK_HEADERS([argz.h \
|
||||||
arpa/inet.h \
|
arpa/inet.h \
|
||||||
fcntl.h \
|
fcntl.h \
|
||||||
|
|
|
@ -329,6 +329,10 @@ SRCS += AppleTLSContext.cc AppleTLSContext.h \
|
||||||
AppleTLSSession.cc AppleTLSSession.h
|
AppleTLSSession.cc AppleTLSSession.h
|
||||||
endif # HAVE_APPLETLS
|
endif # HAVE_APPLETLS
|
||||||
|
|
||||||
|
if USE_WINDOWS_MD
|
||||||
|
SRCS += WinMessageDigestImpl.cc WinMessageDigestImpl.h
|
||||||
|
endif # USE_WINDOWS_MD
|
||||||
|
|
||||||
if HAVE_LIBGNUTLS
|
if HAVE_LIBGNUTLS
|
||||||
SRCS += LibgnutlsTLSContext.cc LibgnutlsTLSContext.h \
|
SRCS += LibgnutlsTLSContext.cc LibgnutlsTLSContext.h \
|
||||||
LibgnutlsTLSSession.cc LibgnutlsTLSSession.h
|
LibgnutlsTLSSession.cc LibgnutlsTLSSession.h
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
|
|
||||||
#ifdef USE_APPLE_MD
|
#ifdef USE_APPLE_MD
|
||||||
# include "AppleMessageDigestImpl.h"
|
# include "AppleMessageDigestImpl.h"
|
||||||
|
#elif defined(USE_WINDOWS_MD)
|
||||||
|
# include "WinMessageDigestImpl.h"
|
||||||
#elif defined(USE_LIBNETTLE_MD)
|
#elif defined(USE_LIBNETTLE_MD)
|
||||||
# include "LibnettleMessageDigestImpl.h"
|
# include "LibnettleMessageDigestImpl.h"
|
||||||
#elif defined(USE_LIBGCRYPT_MD)
|
#elif defined(USE_LIBGCRYPT_MD)
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
/* <!-- copyright */
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Nils Maier
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give
|
||||||
|
* permission to link the code of portions of this program with the
|
||||||
|
* OpenSSL library under certain conditions as described in each
|
||||||
|
* individual source file, and distribute linked combinations
|
||||||
|
* including the two.
|
||||||
|
* You must obey the GNU General Public License in all respects
|
||||||
|
* for all of the code used other than OpenSSL. If you modify
|
||||||
|
* file(s) with this exception, you may extend this exception to your
|
||||||
|
* version of the file(s), but you are not obligated to do so. If you
|
||||||
|
* do not wish to do so, delete this exception statement from your
|
||||||
|
* version. If you delete this exception statement from all source
|
||||||
|
* files in the program, then also delete it here.
|
||||||
|
*/
|
||||||
|
/* copyright --> */
|
||||||
|
|
||||||
|
#include "WinMessageDigestImpl.h"
|
||||||
|
|
||||||
|
#include <wincrypt.h>
|
||||||
|
|
||||||
|
#include "array_fun.h"
|
||||||
|
#include "a2functional.h"
|
||||||
|
#include "HashFuncEntry.h"
|
||||||
|
#include "DlAbortEx.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using namespace aria2;
|
||||||
|
|
||||||
|
class Context {
|
||||||
|
private:
|
||||||
|
HCRYPTPROV provider_;
|
||||||
|
public:
|
||||||
|
Context() {
|
||||||
|
if (!::CryptAcquireContext(&provider_, nullptr, nullptr, PROV_RSA_FULL,
|
||||||
|
CRYPT_VERIFYCONTEXT)) {
|
||||||
|
throw DL_ABORT_EX("Failed to get cryptographic provider");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~Context() {
|
||||||
|
::CryptReleaseContext(provider_, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
HCRYPTPROV get() {
|
||||||
|
return provider_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// XXX static OK?
|
||||||
|
static Context context_;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
template<ALG_ID id>
|
||||||
|
class MessageDigestBase : public MessageDigestImpl {
|
||||||
|
private:
|
||||||
|
HCRYPTHASH hash_;
|
||||||
|
DWORD len_;
|
||||||
|
|
||||||
|
void destroy() {
|
||||||
|
if (hash_) {
|
||||||
|
::CryptDestroyHash(hash_);
|
||||||
|
hash_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
MessageDigestBase() : hash_(0), len_(0) { reset(); }
|
||||||
|
virtual ~MessageDigestBase() { destroy(); }
|
||||||
|
|
||||||
|
virtual size_t getDigestLength() const CXX11_OVERRIDE {
|
||||||
|
return len_;
|
||||||
|
}
|
||||||
|
virtual void reset() CXX11_OVERRIDE {
|
||||||
|
destroy();
|
||||||
|
if (!::CryptCreateHash(context_.get(), id, 0, 0, &hash_)) {
|
||||||
|
throw DL_ABORT_EX("Failed to create hash");
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD len = sizeof(len_);
|
||||||
|
if (!::CryptGetHashParam(hash_, HP_HASHSIZE, reinterpret_cast<BYTE*>(&len_),
|
||||||
|
&len, 0)) {
|
||||||
|
throw DL_ABORT_EX("Failed to create hash");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void update(const void* data, size_t length) CXX11_OVERRIDE {
|
||||||
|
auto bytes = reinterpret_cast<const unsigned char*>(data);
|
||||||
|
while (length) {
|
||||||
|
DWORD l = std::min(length, (size_t)std::numeric_limits<uint32_t>::max());
|
||||||
|
if (!::CryptHashData(hash_, bytes, l, 0)) {
|
||||||
|
throw DL_ABORT_EX("Failed to update hash");
|
||||||
|
}
|
||||||
|
length -= l;
|
||||||
|
bytes += l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void digest(unsigned char* md) CXX11_OVERRIDE {
|
||||||
|
DWORD len = len_;
|
||||||
|
if (!::CryptGetHashParam(hash_, HP_HASHVAL, md, &len, 0)) {
|
||||||
|
throw DL_ABORT_EX("Failed to create hash digest");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef MessageDigestBase<CALG_MD5> MessageDigestMD5;
|
||||||
|
typedef MessageDigestBase<CALG_SHA1> MessageDigestSHA1;
|
||||||
|
typedef MessageDigestBase<CALG_SHA_256> MessageDigestSHA256;
|
||||||
|
typedef MessageDigestBase<CALG_SHA_384> MessageDigestSHA384;
|
||||||
|
typedef MessageDigestBase<CALG_SHA_512> MessageDigestSHA512;
|
||||||
|
|
||||||
|
std::unique_ptr<MessageDigestImpl> MessageDigestImpl::sha1()
|
||||||
|
{
|
||||||
|
return std::unique_ptr<MessageDigestImpl>(new MessageDigestSHA1());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<MessageDigestImpl> MessageDigestImpl::create(
|
||||||
|
const std::string& hashType)
|
||||||
|
{
|
||||||
|
if (hashType == "sha-1") {
|
||||||
|
return make_unique<MessageDigestSHA1>();
|
||||||
|
}
|
||||||
|
if (hashType == "sha-256") {
|
||||||
|
return make_unique<MessageDigestSHA256>();
|
||||||
|
}
|
||||||
|
if (hashType == "sha-384") {
|
||||||
|
return make_unique<MessageDigestSHA384>();
|
||||||
|
}
|
||||||
|
if (hashType == "sha-512") {
|
||||||
|
return make_unique<MessageDigestSHA512>();
|
||||||
|
}
|
||||||
|
if (hashType == "md5") {
|
||||||
|
return make_unique<MessageDigestMD5>();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageDigestImpl::supports(const std::string& hashType)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return !!create(hashType);
|
||||||
|
}
|
||||||
|
catch (RecoverableException& ex) {
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MessageDigestImpl::getDigestLength(const std::string& hashType)
|
||||||
|
{
|
||||||
|
std::unique_ptr<MessageDigestImpl> impl = create(hashType);
|
||||||
|
if (!impl) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return impl->getDigestLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace aria2
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* <!-- copyright */
|
||||||
|
/*
|
||||||
|
* aria2 - The high speed download utility
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Nils Maier
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give
|
||||||
|
* permission to link the code of portions of this program with the
|
||||||
|
* OpenSSL library under certain conditions as described in each
|
||||||
|
* individual source file, and distribute linked combinations
|
||||||
|
* including the two.
|
||||||
|
* You must obey the GNU General Public License in all respects
|
||||||
|
* for all of the code used other than OpenSSL. If you modify
|
||||||
|
* file(s) with this exception, you may extend this exception to your
|
||||||
|
* version of the file(s), but you are not obligated to do so. If you
|
||||||
|
* do not wish to do so, delete this exception statement from your
|
||||||
|
* version. If you delete this exception statement from all source
|
||||||
|
* files in the program, then also delete it here.
|
||||||
|
*/
|
||||||
|
/* copyright --> */
|
||||||
|
#ifndef D_WIN_MESSAGE_DIGEST_IMPL_H
|
||||||
|
#define D_WIN_MESSAGE_DIGEST_IMPL_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace aria2 {
|
||||||
|
|
||||||
|
class MessageDigestImpl {
|
||||||
|
public:
|
||||||
|
virtual ~MessageDigestImpl() {}
|
||||||
|
static std::unique_ptr<MessageDigestImpl> sha1();
|
||||||
|
static std::unique_ptr<MessageDigestImpl> create(const std::string& hashType);
|
||||||
|
|
||||||
|
static bool supports(const std::string& hashType);
|
||||||
|
static size_t getDigestLength(const std::string& hashType);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual size_t getDigestLength() const = 0;
|
||||||
|
virtual void reset() = 0;
|
||||||
|
virtual void update(const void* data, size_t length) = 0;
|
||||||
|
virtual void digest(unsigned char* md) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MessageDigestImpl() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MessageDigestImpl(const MessageDigestImpl&);
|
||||||
|
MessageDigestImpl& operator=(const MessageDigestImpl&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace aria2
|
||||||
|
|
||||||
|
#endif // D_WIN_MESSAGE_DIGEST_IMPL_H
|
Loading…
Reference in New Issue