From a5bf809b80ba0c92c3426dc5359abc385ce1cd76 Mon Sep 17 00:00:00 2001 From: Peter Stuge Date: Sun, 15 Sep 2013 13:32:38 +0200 Subject: [PATCH] Revert "Added Windows Cryptography API: Next Generation based backend" This reverts commit d385230e15715e67796f16f3e65fd899f21a638b. --- Makefile.inc | 5 +- configure.ac | 44 +- src/crypto.h | 4 - src/openssl.c | 2 - src/pem.c | 8 +- src/wincng.c | 1798 ------------------------------------------------- src/wincng.h | 327 --------- 7 files changed, 8 insertions(+), 2180 deletions(-) delete mode 100644 src/wincng.c delete mode 100644 src/wincng.h diff --git a/Makefile.inc b/Makefile.inc index d57e3a8..12a89e5 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -1,8 +1,7 @@ CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \ packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \ version.c knownhost.c agent.c openssl.c libgcrypt.c pem.c keepalive.c \ - global.c wincng.c + global.c HHEADERS = libssh2_priv.h openssl.h libgcrypt.h transport.h channel.h \ - comp.h mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h \ - wincng.h + comp.h mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h diff --git a/configure.ac b/configure.ac index c026dc6..6c2f519 100644 --- a/configure.ac +++ b/configure.ac @@ -92,9 +92,6 @@ AC_ARG_WITH(openssl, AC_ARG_WITH(libz, AC_HELP_STRING([--with-libz],[Use Libz for compression]), use_libz=$withval,use_libz=auto) -AC_ARG_WITH(wincng, - AC_HELP_STRING([--with-wincng],[Use Windows CNG crypto]), - use_wincng=$withval,use_wincng=auto) # Look for OpenSSL (default) if test "$use_openssl" != "no" && test "$use_libgcrypt" != "yes"; then @@ -105,45 +102,21 @@ fi # Look for libgcrypt if test "$ac_cv_libssl" != "yes" && test "$use_libgcrypt" != "no"; then AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include ]) -fi - -# Look for Windows Cryptography API: Next Generation -if test "$ac_cv_libssl" != "yes" && test "$use_wincng" != "no"; then - AC_LIB_HAVE_LINKFLAGS([bcrypt], [], [ - #include - #include - ]) - AC_LIB_HAVE_LINKFLAGS([crypt32], [], [ - #include - #include - ]) - AC_CHECK_HEADERS([ntdef.h ntstatus.h], [], [], [ - #include - ]) + LIBS="$LIBS -lgcrypt" fi AC_SUBST(LIBSREQUIRED) -if test "$ac_cv_libssl" != "yes" && test "$ac_cv_libgcrypt" != "yes" && test "$ac_cv_libbcrypt" != "yes"; then - AC_MSG_ERROR([cannot find OpenSSL or Libgcrypt or Windows CNG, +if test "$ac_cv_libssl" != "yes" && test "$ac_cv_libgcrypt" != "yes"; then + AC_MSG_ERROR([cannot find OpenSSL or Libgcrypt, try --with-libssl-prefix=PATH or --with-libgcrypt-prefix=PATH]) fi if test "$ac_cv_libgcrypt" = "yes"; then AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use libgcrypt]) - LIBS="$LIBS -lgcrypt" fi AM_CONDITIONAL(LIBGCRYPT, test "$ac_cv_libgcrypt" = "yes") -if test "$ac_cv_libbcrypt" = "yes"; then - AC_DEFINE(LIBSSH2_WINCNG, 1, [Use Windows CNG]) - LIBS="$LIBS -lbcrypt" - if test "$ac_cv_libcrypt32" = "yes"; then - LIBS="$LIBS -lcrypt32" - fi -fi -AM_CONDITIONAL(WINCNG, test "$ac_cv_libbcrypt" = "yes") - # Not all OpenSSL have AES-CTR functions. if test "$ac_cv_libssl" = "yes"; then save_LDFLAGS="$LDFLAGS" @@ -181,13 +154,6 @@ if test "$GEX_NEW" != "no"; then AC_DEFINE(LIBSSH2_DH_GEX_NEW, 1, [Enable newer diffie-hellman-group-exchange-sha1 syntax]) fi -AC_ARG_ENABLE(memory-overwrite, - AC_HELP_STRING([--disable-memory-overwrite],[Disable memory overwrite before being freed]), - [MEMORY_OVERWRITE=$enableval]) -if test "$MEMORY_OVERWRITE" != "no"; then - AC_DEFINE(LIBSSH2_MEMORY_OVERWRITE, 1, [Enable memory overwrite before being freed]) -fi - dnl ************************************************************ dnl option to switch on compiler debug options dnl @@ -273,7 +239,7 @@ AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"]) # AC_HEADER_STDC AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h]) AC_CHECK_HEADERS([sys/select.h sys/socket.h sys/ioctl.h sys/time.h]) -AC_CHECK_HEADERS([arpa/inet.h netinet/in.h math.h]) +AC_CHECK_HEADERS([arpa/inet.h netinet/in.h]) AC_CHECK_HEADERS([sys/un.h], [have_sys_un_h=yes], [have_sys_un_h=no]) AM_CONDITIONAL([HAVE_SYS_UN_H], test "x$have_sys_un_h" = xyes) @@ -352,7 +318,7 @@ AC_MSG_NOTICE([summary of build options: Compiler: ${CC} Compiler flags: ${CFLAGS} Library types: Shared=${enable_shared}, Static=${enable_static} - Crypto library: openssl: ${ac_cv_libssl:-no} (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A}) libgcrypt: ${ac_cv_libgcrypt:-no} wincng: ${ac_cv_libbcrypt:-no} + Crypto library: openssl: ${ac_cv_libssl:-no} (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A}) libgcrypt: ${ac_cv_libgcrypt:-no} Debug build: $enable_debug Build examples: $build_examples Path to sshd: $ac_cv_path_SSHD (only for self-tests) diff --git a/src/crypto.h b/src/crypto.h index ae1fdd6..fb576b6 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -41,12 +41,8 @@ #ifdef LIBSSH2_LIBGCRYPT #include "libgcrypt.h" #else -#ifdef LIBSSH2_WINCNG -#include "wincng.h" -#else #include "openssl.h" #endif -#endif int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa, const unsigned char *edata, diff --git a/src/openssl.c b/src/openssl.c index b1783a1..29c8f47 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -41,7 +41,6 @@ #include "libssh2_priv.h" #ifndef LIBSSH2_LIBGCRYPT /* compile only if we build with OpenSSL */ -#ifndef LIBSSH2_WINCNG #include @@ -802,5 +801,4 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, return st; } -#endif /* !LIBSSH2_WINCNG */ #endif /* !LIBSSH2_LIBGCRYPT */ diff --git a/src/pem.c b/src/pem.c index 374870b..5749bc8 100644 --- a/src/pem.c +++ b/src/pem.c @@ -38,8 +38,7 @@ #include "libssh2_priv.h" -/* compile only if we build with libgcrypt or wincng */ -#if defined(LIBSSH2_LIBGCRYPT) || defined(LIBSSH2_WINCNG) +#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */ static int readline(char *line, int line_size, FILE * fp) @@ -114,11 +113,6 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session, return ret; } -#endif /* LIBSSH2_LIBGCRYPT or LIBSSH2_WINCNG */ - -/* compile only if we build with libgcrypt */ -#ifdef LIBSSH2_LIBGCRYPT - static int read_asn1_length(const unsigned char *data, unsigned int datalen, unsigned int *len) diff --git a/src/wincng.c b/src/wincng.c deleted file mode 100644 index 5791e7b..0000000 --- a/src/wincng.c +++ /dev/null @@ -1,1798 +0,0 @@ -/* - * Copyright (C) 2013 Marc Hoersken - * All rights reserved. - * - * Redistribution and use in source and binary forms, - * with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * - * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Neither the name of the copyright holder nor the names - * of any other contributors may be used to endorse or - * promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - -#include "libssh2_priv.h" - -#ifdef LIBSSH2_WINCNG /* compile only if we build with wincng */ - -#ifdef HAVE_MATH_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_LIBCRYPT32 -#include -#endif - - -/*******************************************************************/ -/* - * Windows CNG backend: Missing definitions (for MinGW[-w64]) - */ -#ifndef BCRYPT_RNG_ALGORITHM -#define BCRYPT_RNG_ALGORITHM L"RNG" -#endif - -#ifndef BCRYPT_MD5_ALGORITHM -#define BCRYPT_MD5_ALGORITHM L"MD5" -#endif - -#ifndef BCRYPT_SHA1_ALGORITHM -#define BCRYPT_SHA1_ALGORITHM L"SHA1" -#endif - -#ifndef BCRYPT_RSA_ALGORITHM -#define BCRYPT_RSA_ALGORITHM L"RSA" -#endif - -#ifndef BCRYPT_DSA_ALGORITHM -#define BCRYPT_DSA_ALGORITHM L"DSA" -#endif - -#ifndef BCRYPT_AES_ALGORITHM -#define BCRYPT_AES_ALGORITHM L"AES" -#endif - -#ifndef BCRYPT_RC4_ALGORITHM -#define BCRYPT_RC4_ALGORITHM L"RC4" -#endif - -#ifndef BCRYPT_3DES_ALGORITHM -#define BCRYPT_3DES_ALGORITHM L"3DES" -#endif - -#ifndef BCRYPT_ALG_HANDLE_HMAC_FLAG -#define BCRYPT_ALG_HANDLE_HMAC_FLAG 0x00000008 -#endif - -#ifndef BCRYPT_DSA_PUBLIC_BLOB -#define BCRYPT_DSA_PUBLIC_BLOB L"DSAPUBLICBLOB" -#endif - -#ifndef BCRYPT_DSA_PUBLIC_MAGIC -#define BCRYPT_DSA_PUBLIC_MAGIC 0x42505344 /* DSPB */ -#endif - -#ifndef BCRYPT_DSA_PRIVATE_BLOB -#define BCRYPT_DSA_PRIVATE_BLOB L"DSAPRIVATEBLOB" -#endif - -#ifndef BCRYPT_DSA_PRIVATE_MAGIC -#define BCRYPT_DSA_PRIVATE_MAGIC 0x56505344 /* DSPV */ -#endif - -#ifndef BCRYPT_RSAPUBLIC_BLOB -#define BCRYPT_RSAPUBLIC_BLOB L"RSAPUBLICBLOB" -#endif - -#ifndef BCRYPT_RSAPUBLIC_MAGIC -#define BCRYPT_RSAPUBLIC_MAGIC 0x31415352 /* RSA1 */ -#endif - -#ifndef BCRYPT_RSAFULLPRIVATE_BLOB -#define BCRYPT_RSAFULLPRIVATE_BLOB L"RSAFULLPRIVATEBLOB" -#endif - -#ifndef BCRYPT_RSAFULLPRIVATE_MAGIC -#define BCRYPT_RSAFULLPRIVATE_MAGIC 0x33415352 /* RSA3 */ -#endif - -#ifndef BCRYPT_KEY_DATA_BLOB -#define BCRYPT_KEY_DATA_BLOB L"KeyDataBlob" -#endif - -#ifndef BCRYPT_MESSAGE_BLOCK_LENGTH -#define BCRYPT_MESSAGE_BLOCK_LENGTH L"MessageBlockLength" -#endif - -#ifndef BCRYPT_NO_KEY_VALIDATION -#define BCRYPT_NO_KEY_VALIDATION 0x00000008 -#endif - -#ifndef BCRYPT_BLOCK_PADDING -#define BCRYPT_BLOCK_PADDING 0x00000001 -#endif - -#ifndef BCRYPT_PAD_NONE -#define BCRYPT_PAD_NONE 0x00000001 -#endif - -#ifndef BCRYPT_PAD_PKCS1 -#define BCRYPT_PAD_PKCS1 0x00000002 -#endif - -#ifndef BCRYPT_PAD_OAEP -#define BCRYPT_PAD_OAEP 0x00000004 -#endif - -#ifndef BCRYPT_PAD_PSS -#define BCRYPT_PAD_PSS 0x00000008 -#endif - -#ifndef CRYPT_STRING_ANY -#define CRYPT_STRING_ANY 0x00000007 -#endif - -#ifndef LEGACY_RSAPRIVATE_BLOB -#define LEGACY_RSAPRIVATE_BLOB L"CAPIPRIVATEBLOB" -#endif - -#ifndef PKCS_RSA_PRIVATE_KEY -#define PKCS_RSA_PRIVATE_KEY (LPCSTR)43 -#endif - - -/*******************************************************************/ -/* - * Windows CNG backend: Generic functions - */ - -void -_libssh2_wincng_init(void) -{ - int ret; - - BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRNG, - BCRYPT_RNG_ALGORITHM, NULL, 0); - - BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashMD5, - BCRYPT_MD5_ALGORITHM, NULL, 0); - BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA1, - BCRYPT_SHA1_ALGORITHM, NULL, 0); - - BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacMD5, - BCRYPT_MD5_ALGORITHM, NULL, - BCRYPT_ALG_HANDLE_HMAC_FLAG); - BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA1, - BCRYPT_SHA1_ALGORITHM, NULL, - BCRYPT_ALG_HANDLE_HMAC_FLAG); - - BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRSA, - BCRYPT_RSA_ALGORITHM, NULL, 0); - BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgDSA, - BCRYPT_DSA_ALGORITHM, NULL, 0); - - ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_CBC, - BCRYPT_AES_ALGORITHM, NULL, 0); - if (ret == STATUS_SUCCESS) { - BCryptSetProperty(_libssh2_wincng.hAlgAES_CBC, BCRYPT_CHAINING_MODE, - (PBYTE)BCRYPT_CHAIN_MODE_CBC, - sizeof(BCRYPT_CHAIN_MODE_CBC), 0); - } - - ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRC4_NA, - BCRYPT_RC4_ALGORITHM, NULL, 0); - if (ret == STATUS_SUCCESS) { - BCryptSetProperty(_libssh2_wincng.hAlgRC4_NA, BCRYPT_CHAINING_MODE, - (PBYTE)BCRYPT_CHAIN_MODE_NA, - sizeof(BCRYPT_CHAIN_MODE_NA), 0); - } - - ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlg3DES_CBC, - BCRYPT_3DES_ALGORITHM, NULL, 0); - if (ret == STATUS_SUCCESS) { - BCryptSetProperty(_libssh2_wincng.hAlg3DES_CBC, BCRYPT_CHAINING_MODE, - (PBYTE)BCRYPT_CHAIN_MODE_CBC, - sizeof(BCRYPT_CHAIN_MODE_CBC), 0); - } -} - -void -_libssh2_wincng_free(void) -{ - BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRNG, 0); - BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashMD5, 0); - BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA1, 0); - BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacMD5, 0); - BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA1, 0); - BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRSA, 0); - BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgDSA, 0); - BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0); - BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0); - BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0); - - memset(&_libssh2_wincng, 0, sizeof(_libssh2_wincng)); -} - -int -_libssh2_wincng_random(void *buf, int len) -{ - return BCryptGenRandom(_libssh2_wincng.hAlgRNG, buf, len, 0) - == STATUS_SUCCESS ? 0 : -1; -} - -static void -_libssh2_wincng_mfree(void *buf, int len) -{ - if (!buf) - return; - -#ifdef LIBSSH2_MEMORY_OVERWRITE - if (len > 0) - _libssh2_wincng_random(buf, len); -#else - (void)len; -#endif - - free(buf); -} - - -/*******************************************************************/ -/* - * Windows CNG backend: Hash functions - */ - -int -_libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx, - BCRYPT_ALG_HANDLE hAlg, unsigned long hashlen, - unsigned char *key, unsigned long keylen) -{ - BCRYPT_HASH_HANDLE hHash; - unsigned char *pbHashObject; - unsigned long dwHashObject, dwHash, cbData; - int ret; - - ret = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, - (unsigned char *)&dwHash, - sizeof(dwHash), - &cbData, 0); - if (ret != STATUS_SUCCESS || dwHash != hashlen) { - return -1; - } - - ret = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, - (unsigned char *)&dwHashObject, - sizeof(dwHashObject), - &cbData, 0); - if (ret != STATUS_SUCCESS) { - return -1; - } - - pbHashObject = malloc(dwHashObject); - if (!pbHashObject) { - return -1; - } - - - ret = BCryptCreateHash(hAlg, &hHash, - pbHashObject, dwHashObject, - key, keylen, 0); - if (ret != STATUS_SUCCESS) { - _libssh2_wincng_mfree(pbHashObject, dwHashObject); - return -1; - } - - - ctx->hHash = hHash; - ctx->pbHashObject = pbHashObject; - ctx->dwHashObject = dwHashObject; - ctx->cbHash = dwHash; - - return 0; -} - -int -_libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, - unsigned char *data, unsigned long datalen) -{ - return BCryptHashData(ctx->hHash, data, datalen, 0) - == STATUS_SUCCESS ? 0 : -1; -} - -int -_libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx, - unsigned char *hash) -{ - int ret; - - ret = BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0); - - BCryptDestroyHash(ctx->hHash); - ctx->hHash = 0; - - _libssh2_wincng_mfree(ctx->pbHashObject, ctx->dwHashObject); - - return ret; -} - -int -_libssh2_wincng_hash(unsigned char *data, unsigned long datalen, - BCRYPT_ALG_HANDLE hAlg, - unsigned char *hash, unsigned long hashlen) -{ - _libssh2_wincng_hash_ctx ctx; - - if (!_libssh2_wincng_hash_init(&ctx, hAlg, hashlen, NULL, 0)) { - if (!_libssh2_wincng_hash_update(&ctx, data, datalen)) { - if (!_libssh2_wincng_hash_final(&ctx, hash)) { - return 0; - } - } - } - - return -1; -} - - -/*******************************************************************/ -/* - * Windows CNG backend: HMAC functions - */ - -int -_libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx, - unsigned char *hash) -{ - return BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0) - == STATUS_SUCCESS ? 0 : -1; -} - -void -_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx) -{ - BCryptDestroyHash(ctx->hHash); - ctx->hHash = 0; - - _libssh2_wincng_mfree(ctx->pbHashObject, ctx->dwHashObject); -} - - -/*******************************************************************/ -/* - * Windows CNG backend: Key functions - */ - -int -_libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx, - const unsigned char *sig, - unsigned long sig_len, - const unsigned char *m, - unsigned long m_len, - unsigned long flags) -{ - BCRYPT_PKCS1_PADDING_INFO paddingInfoPKCS1; - void *pPaddingInfo; - unsigned char *data, *hash; - unsigned long datalen, hashlen; - int ret; - - datalen = m_len; - data = malloc(datalen); - if (!data) { - return -1; - } - - hashlen = SHA_DIGEST_LENGTH; - hash = malloc(hashlen); - if (!hash) { - free(data); - return -1; - } - - memcpy(data, m, datalen); - - ret = _libssh2_wincng_hash(data, datalen, - _libssh2_wincng.hAlgHashSHA1, - hash, hashlen); - - _libssh2_wincng_mfree(data, datalen); - - if (ret) { - _libssh2_wincng_mfree(hash, hashlen); - return -1; - } - - datalen = sig_len; - data = malloc(datalen); - if (!data) { - _libssh2_wincng_mfree(hash, hashlen); - return -1; - } - - if (flags & BCRYPT_PAD_PKCS1) { - paddingInfoPKCS1.pszAlgId = BCRYPT_SHA1_ALGORITHM; - pPaddingInfo = &paddingInfoPKCS1; - } - - memcpy(data, sig, datalen); - - ret = BCryptVerifySignature(ctx->hKey, pPaddingInfo, - hash, hashlen, data, datalen, flags); - - _libssh2_wincng_mfree(hash, hashlen); - _libssh2_wincng_mfree(data, datalen); - - return ret == STATUS_SUCCESS ? 0 : -1; -} - -#ifdef HAVE_LIBCRYPT32 -static int -_libssh2_wincng_load_pem(LIBSSH2_SESSION *session, - const char *filename, - const char *passphrase, - const char *headerbegin, - const char *headerend, - unsigned char **data, - unsigned int *datalen) -{ - FILE *fp; - int ret; - - (void)passphrase; - - fp = fopen(filename, "r"); - if (!fp) { - return -1; - } - - ret = _libssh2_pem_parse(session, headerbegin, headerend, - fp, data, datalen); - - fclose(fp); - - return ret; -} - -static int -_libssh2_wincng_load_private(LIBSSH2_SESSION *session, - const char *filename, - const char *passphrase, - unsigned char **ppbEncoded, - unsigned long *pcbEncoded) -{ - unsigned char *data; - int ret, datalen; - - ret = _libssh2_wincng_load_pem(session, filename, passphrase, - "-----BEGIN RSA PRIVATE KEY-----", - "-----END RSA PRIVATE KEY-----", - &data, &datalen); - - if (ret) { - ret = _libssh2_wincng_load_pem(session, filename, passphrase, - "-----BEGIN DSA PRIVATE KEY-----", - "-----END DSA PRIVATE KEY-----", - &data, &datalen); - } - - if (!ret) { - *ppbEncoded = data; - *pcbEncoded = datalen; - } - - return ret; -} - -static int -_libssh2_wincng_asn_decode(unsigned char *pbEncoded, - unsigned long cbEncoded, - LPCSTR lpszStructType, - unsigned char **ppbDecoded, - unsigned long *pcbDecoded) -{ - unsigned char *pbDecoded; - unsigned long cbDecoded; - int ret; - - ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - lpszStructType, - pbEncoded, cbEncoded, 0, NULL, - NULL, &cbDecoded); - if (!ret) { - return -1; - } - - pbDecoded = malloc(cbDecoded); - if (!pbDecoded) { - return -1; - } - - ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - lpszStructType, - pbEncoded, cbEncoded, 0, NULL, - pbDecoded, &cbDecoded); - if (!ret) { - _libssh2_wincng_mfree(pbDecoded, cbDecoded); - return -1; - } - - - *ppbDecoded = pbDecoded; - *pcbDecoded = cbDecoded; - - return 0; -} - -static int -_libssh2_wincng_bn_ltob(unsigned char *pbInput, - unsigned long cbInput, - unsigned char **ppbOutput, - unsigned long *pcbOutput) -{ - unsigned char *pbOutput; - unsigned long cbOutput, index, offset, length; - - if (cbInput < 1) { - return 0; - } - - offset = 0; - length = cbInput - 1; - cbOutput = cbInput; - if (pbInput[length] & (1 << 7)) { - offset++; - cbOutput++; - } - - pbOutput = malloc(cbOutput); - if (!pbOutput) { - return -1; - } - - pbOutput[0] = 0; - for (index = 0; index < cbInput; index++) { - pbOutput[index + offset] = pbInput[length - index]; - } - - - *ppbOutput = pbOutput; - *pcbOutput = cbOutput; - - return 0; -} - -static int -_libssh2_wincng_asn_decode_bn(unsigned char *pbEncoded, - unsigned long cbEncoded, - unsigned char **ppbDecoded, - unsigned long *pcbDecoded) -{ - unsigned char *pbDecoded, *pbInteger; - unsigned long cbDecoded, cbInteger; - int ret; - - ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded, - X509_MULTI_BYTE_UINT, - &pbInteger, &cbInteger); - if (!ret) { - ret = _libssh2_wincng_bn_ltob(((PCRYPT_DATA_BLOB)pbInteger)->pbData, - ((PCRYPT_DATA_BLOB)pbInteger)->cbData, - &pbDecoded, &cbDecoded); - if (!ret) { - *ppbDecoded = pbDecoded; - *pcbDecoded = cbDecoded; - } - _libssh2_wincng_mfree(pbInteger, cbInteger); - } - - return ret; -} - -static int -_libssh2_wincng_asn_decode_bns(unsigned char *pbEncoded, - unsigned long cbEncoded, - unsigned char ***prpbDecoded, - unsigned long **prcbDecoded, - unsigned long *pcbCount) -{ - PCRYPT_DER_BLOB pBlob; - unsigned char *pbDecoded, **rpbDecoded; - unsigned long cbDecoded, *rcbDecoded, index, length; - int ret; - - ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded, - X509_SEQUENCE_OF_ANY, - &pbDecoded, &cbDecoded); - if (!ret) { - length = ((PCRYPT_DATA_BLOB)pbDecoded)->cbData; - - rpbDecoded = malloc(sizeof(PBYTE) * length); - if (rpbDecoded) { - rcbDecoded = malloc(sizeof(DWORD) * length); - if (rcbDecoded) { - for (index = 0; index < length; index++) { - pBlob = &((PCRYPT_DER_BLOB) - ((PCRYPT_DATA_BLOB)pbDecoded)->pbData)[index]; - ret = _libssh2_wincng_asn_decode_bn(pBlob->pbData, - pBlob->cbData, - &rpbDecoded[index], - &rcbDecoded[index]); - if (ret) - break; - } - - if (ret) { - for (length = 0; length < index; length++) - _libssh2_wincng_mfree(rpbDecoded[length], - rcbDecoded[length]); - } else { - *prpbDecoded = rpbDecoded; - *prcbDecoded = rcbDecoded; - *pcbCount = length; - } - } else { - free(rpbDecoded); - ret = -1; - } - - } else { - ret = -1; - } - - _libssh2_wincng_mfree(pbDecoded, cbDecoded); - } - - return ret; -} -#endif /* HAVE_LIBCRYPT32 */ - -static unsigned long -_libssh2_wincng_bn_size(const unsigned char *bignum, - unsigned long length) -{ - unsigned long offset; - - if (!bignum) - return 0; - - length--; - - offset = 0; - while (!(*(bignum + offset)) && (offset < length)) - offset++; - - length++; - - return length - offset; -} - - -/*******************************************************************/ -/* - * Windows CNG backend: RSA functions - */ - -int -_libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa, - const unsigned char *edata, - unsigned long elen, - const unsigned char *ndata, - unsigned long nlen, - const unsigned char *ddata, - unsigned long dlen, - const unsigned char *pdata, - unsigned long plen, - const unsigned char *qdata, - unsigned long qlen, - const unsigned char *e1data, - unsigned long e1len, - const unsigned char *e2data, - unsigned long e2len, - const unsigned char *coeffdata, - unsigned long coefflen) -{ - BCRYPT_KEY_HANDLE hKey; - BCRYPT_RSAKEY_BLOB *rsakey; - LPCWSTR lpszBlobType; - unsigned char *key; - unsigned long keylen, offset, mlen, p1len, p2len; - int ret; - - mlen = max(_libssh2_wincng_bn_size(ndata, nlen), - _libssh2_wincng_bn_size(ddata, dlen)); - offset = sizeof(BCRYPT_RSAKEY_BLOB); - keylen = offset + elen + mlen; - if (ddata && dlen > 0) { - p1len = max(_libssh2_wincng_bn_size(pdata, plen), - _libssh2_wincng_bn_size(e1data, e1len)); - p2len = max(_libssh2_wincng_bn_size(qdata, qlen), - _libssh2_wincng_bn_size(e2data, e2len)); - keylen += p1len * 3 + p2len * 2 + mlen; - } - - key = malloc(keylen); - if (!key) { - return -1; - } - - memset(key, 0, keylen); - - - /* http://msdn.microsoft.com/library/windows/desktop/aa375531.aspx */ - rsakey = (BCRYPT_RSAKEY_BLOB *)key; - rsakey->BitLength = mlen * 8; - rsakey->cbPublicExp = elen; - rsakey->cbModulus = mlen; - - memcpy(key + offset, edata, elen); - offset += elen; - - if (nlen < mlen) - memcpy(key + offset + mlen - nlen, ndata, nlen); - else - memcpy(key + offset, ndata + nlen - mlen, mlen); - - if (ddata && dlen > 0) { - offset += mlen; - - if (plen < p1len) - memcpy(key + offset + p1len - plen, pdata, plen); - else - memcpy(key + offset, pdata + plen - p1len, p1len); - offset += p1len; - - if (qlen < p2len) - memcpy(key + offset + p2len - qlen, qdata, qlen); - else - memcpy(key + offset, qdata + qlen - p2len, p2len); - offset += p2len; - - if (e1len < p1len) - memcpy(key + offset + p1len - e1len, e1data, e1len); - else - memcpy(key + offset, e1data + e1len - p1len, p1len); - offset += p1len; - - if (e2len < p2len) - memcpy(key + offset + p2len - e2len, e2data, e2len); - else - memcpy(key + offset, e2data + e2len - p2len, p2len); - offset += p2len; - - if (coefflen < p1len) - memcpy(key + offset + p1len - coefflen, coeffdata, coefflen); - else - memcpy(key + offset, coeffdata + coefflen - p1len, p1len); - offset += p1len; - - if (dlen < mlen) - memcpy(key + offset + mlen - dlen, ddata, dlen); - else - memcpy(key + offset, ddata + dlen - mlen, mlen); - - lpszBlobType = BCRYPT_RSAFULLPRIVATE_BLOB; - rsakey->Magic = BCRYPT_RSAFULLPRIVATE_MAGIC; - rsakey->cbPrime1 = p1len; - rsakey->cbPrime2 = p2len; - } else { - lpszBlobType = BCRYPT_RSAPUBLIC_BLOB; - rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; - rsakey->cbPrime1 = 0; - rsakey->cbPrime2 = 0; - } - - - ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, lpszBlobType, - &hKey, key, keylen, 0); - if (ret != STATUS_SUCCESS) { - _libssh2_wincng_mfree(key, keylen); - return -1; - } - - - *rsa = malloc(sizeof(libssh2_rsa_ctx)); - if (!(*rsa)) { - BCryptDestroyKey(hKey); - _libssh2_wincng_mfree(key, keylen); - return -1; - } - - (*rsa)->hKey = hKey; - (*rsa)->pbKeyObject = key; - (*rsa)->cbKeyObject = keylen; - - return 0; -} - -int -_libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa, - LIBSSH2_SESSION *session, - const char *filename, - const unsigned char *passphrase) -{ -#ifdef HAVE_LIBCRYPT32 - BCRYPT_KEY_HANDLE hKey; - unsigned char *pbEncoded, *pbStructInfo; - unsigned long cbEncoded, cbStructInfo; - int ret; - - (void)session; - - ret = _libssh2_wincng_load_private(session, filename, - (const char *)passphrase, - &pbEncoded, &cbEncoded); - if (ret) { - return -1; - } - - ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded, - PKCS_RSA_PRIVATE_KEY, - &pbStructInfo, &cbStructInfo); - - _libssh2_wincng_mfree(pbEncoded, cbEncoded); - - if (ret) { - return -1; - } - - - ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, - LEGACY_RSAPRIVATE_BLOB, &hKey, - pbStructInfo, cbStructInfo, 0); - if (ret != STATUS_SUCCESS) { - _libssh2_wincng_mfree(pbStructInfo, cbStructInfo); - return -1; - } - - - *rsa = malloc(sizeof(libssh2_rsa_ctx)); - if (!(*rsa)) { - BCryptDestroyKey(hKey); - _libssh2_wincng_mfree(pbStructInfo, cbStructInfo); - return -1; - } - - (*rsa)->hKey = hKey; - (*rsa)->pbKeyObject = pbStructInfo; - (*rsa)->cbKeyObject = cbStructInfo; - - return 0; -#else - (void)rsa; - (void)filename; - (void)passphrase; - - return _libssh2_error(session, LIBSSH2_ERROR_FILE, - "Unable to load RSA key from private key file: " - "Method unsupported in Windows CNG backend"); -#endif /* HAVE_LIBCRYPT32 */ -} - -int -_libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa, - const unsigned char *sig, - unsigned long sig_len, - const unsigned char *m, - unsigned long m_len) -{ - return _libssh2_wincng_key_sha1_verify(rsa, sig, sig_len, m, m_len, - BCRYPT_PAD_PKCS1); -} - -int -_libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session, - libssh2_rsa_ctx *rsa, - const unsigned char *hash, - size_t hash_len, - unsigned char **signature, - size_t *signature_len) -{ - BCRYPT_PKCS1_PADDING_INFO paddingInfo; - unsigned char *data, *sig; - unsigned long cbData, datalen, siglen; - int ret; - - datalen = hash_len; - data = malloc(datalen); - if (!data) { - return -1; - } - - paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM; - - memcpy(data, hash, datalen); - - ret = BCryptSignHash(rsa->hKey, &paddingInfo, - data, datalen, NULL, 0, - &cbData, BCRYPT_PAD_PKCS1); - if (ret == STATUS_SUCCESS) { - siglen = cbData; - sig = LIBSSH2_ALLOC(session, siglen); - if (sig) { - ret = BCryptSignHash(rsa->hKey, &paddingInfo, - data, datalen, sig, siglen, - &cbData, BCRYPT_PAD_PKCS1); - if (ret == STATUS_SUCCESS) { - *signature_len = siglen; - *signature = sig; - } else { - LIBSSH2_FREE(session, sig); - } - } else - ret = STATUS_NO_MEMORY; - } - - _libssh2_wincng_mfree(data, datalen); - - return ret == STATUS_SUCCESS ? 0 : -1; -} - -void -_libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa) -{ - BCryptDestroyKey(rsa->hKey); - - _libssh2_wincng_mfree(rsa->pbKeyObject, rsa->cbKeyObject); - _libssh2_wincng_mfree(rsa, sizeof(libssh2_rsa_ctx)); -} - - -/*******************************************************************/ -/* - * Windows CNG backend: DSA functions - */ - -#if LIBSSH2_DSA -int -_libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa, - const unsigned char *pdata, - unsigned long plen, - const unsigned char *qdata, - unsigned long qlen, - const unsigned char *gdata, - unsigned long glen, - const unsigned char *ydata, - unsigned long ylen, - const unsigned char *xdata, - unsigned long xlen) -{ - BCRYPT_KEY_HANDLE hKey; - BCRYPT_DSA_KEY_BLOB *dsakey; - LPCWSTR lpszBlobType; - unsigned char *key; - unsigned long keylen, offset, length; - int ret; - - length = max(max(_libssh2_wincng_bn_size(pdata, plen), - _libssh2_wincng_bn_size(gdata, glen)), - _libssh2_wincng_bn_size(ydata, ylen)); - offset = sizeof(BCRYPT_DSA_KEY_BLOB); - keylen = offset + length * 3; - if (xdata && xlen > 0) - keylen += 20; - - key = malloc(keylen); - if (!key) { - return -1; - } - - memset(key, 0, keylen); - - - /* http://msdn.microsoft.com/library/windows/desktop/aa833126.aspx */ - dsakey = (BCRYPT_DSA_KEY_BLOB *)key; - dsakey->cbKey = length; - - memset(dsakey->Count, -1, sizeof(dsakey->Count)); - memset(dsakey->Seed, -1, sizeof(dsakey->Seed)); - - if (qlen < 20) - memcpy(dsakey->q + 20 - qlen, qdata, qlen); - else - memcpy(dsakey->q, qdata + qlen - 20, 20); - - if (plen < length) - memcpy(key + offset + length - plen, pdata, plen); - else - memcpy(key + offset, pdata + plen - length, length); - offset += length; - - if (glen < length) - memcpy(key + offset + length - glen, gdata, glen); - else - memcpy(key + offset, gdata + glen - length, length); - offset += length; - - if (ylen < length) - memcpy(key + offset + length - ylen, ydata, ylen); - else - memcpy(key + offset, ydata + ylen - length, length); - - if (xdata && xlen > 0) { - offset += length; - - if (xlen < 20) - memcpy(key + offset + 20 - xlen, xdata, xlen); - else - memcpy(key + offset, xdata + xlen - 20, 20); - - lpszBlobType = BCRYPT_DSA_PRIVATE_BLOB; - dsakey->dwMagic = BCRYPT_DSA_PRIVATE_MAGIC; - } else { - lpszBlobType = BCRYPT_DSA_PUBLIC_BLOB; - dsakey->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC; - } - - - ret = BCryptImportKeyPair(_libssh2_wincng.hAlgDSA, NULL, lpszBlobType, - &hKey, key, keylen, 0); - if (ret != STATUS_SUCCESS) { - _libssh2_wincng_mfree(key, keylen); - return -1; - } - - - *dsa = malloc(sizeof(libssh2_dsa_ctx)); - if (!(*dsa)) { - BCryptDestroyKey(hKey); - _libssh2_wincng_mfree(key, keylen); - return -1; - } - - (*dsa)->hKey = hKey; - (*dsa)->pbKeyObject = key; - (*dsa)->cbKeyObject = keylen; - - return 0; -} - -int -_libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa, - LIBSSH2_SESSION *session, - const char *filename, - const unsigned char *passphrase) -{ -#ifdef HAVE_LIBCRYPT32 - unsigned char *pbEncoded, **rpbDecoded; - unsigned long cbEncoded, *rcbDecoded, index, length; - int ret; - - (void)session; - - ret = _libssh2_wincng_load_private(session, filename, - (const char *)passphrase, - &pbEncoded, &cbEncoded); - if (ret) { - return -1; - } - - ret = _libssh2_wincng_asn_decode_bns(pbEncoded, cbEncoded, - &rpbDecoded, &rcbDecoded, &length); - - _libssh2_wincng_mfree(pbEncoded, cbEncoded); - - if (ret) { - return -1; - } - - - if (length == 6) { - ret = _libssh2_wincng_dsa_new(dsa, - rpbDecoded[1], rcbDecoded[1], - rpbDecoded[2], rcbDecoded[2], - rpbDecoded[3], rcbDecoded[3], - rpbDecoded[4], rcbDecoded[4], - rpbDecoded[5], rcbDecoded[5]); - } else { - ret = -1; - } - - for (index = 0; index < length; index++) - _libssh2_wincng_mfree(rpbDecoded[index], rcbDecoded[index]); - - free(rpbDecoded); - free(rcbDecoded); - - return ret; -#else - (void)dsa; - (void)filename; - (void)passphrase; - - return _libssh2_error(session, LIBSSH2_ERROR_FILE, - "Unable to load DSA key from private key file: " - "Method unsupported in Windows CNG backend"); -#endif /* HAVE_LIBCRYPT32 */ -} - -int -_libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa, - const unsigned char *sig_fixed, - const unsigned char *m, - unsigned long m_len) -{ - return _libssh2_wincng_key_sha1_verify(dsa, sig_fixed, 40, m, m_len, 0); -} - -int -_libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa, - const unsigned char *hash, - unsigned long hash_len, - unsigned char *sig_fixed) -{ - unsigned char *data, *sig; - unsigned long cbData, datalen, siglen; - int ret; - - datalen = hash_len; - data = malloc(datalen); - if (!data) { - return -1; - } - - memcpy(data, hash, datalen); - - ret = BCryptSignHash(dsa->hKey, NULL, data, datalen, - NULL, 0, &cbData, 0); - if (ret == STATUS_SUCCESS) { - siglen = cbData; - if (siglen == 40) { - sig = malloc(siglen); - if (sig) { - ret = BCryptSignHash(dsa->hKey, NULL, data, datalen, - sig, siglen, &cbData, 0); - if (ret == STATUS_SUCCESS) { - memcpy(sig_fixed, sig, siglen); - } - - _libssh2_wincng_mfree(sig, siglen); - } else - ret = STATUS_NO_MEMORY; - } else - ret = STATUS_NO_MEMORY; - } - - _libssh2_wincng_mfree(data, datalen); - - return ret == STATUS_SUCCESS ? 0 : -1; -} - -void -_libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa) -{ - BCryptDestroyKey(dsa->hKey); - - _libssh2_wincng_mfree(dsa->pbKeyObject, dsa->cbKeyObject); - _libssh2_wincng_mfree(dsa, sizeof(libssh2_dsa_ctx)); -} -#endif - - -/*******************************************************************/ -/* - * Windows CNG backend: Key functions - */ - -static unsigned long -_libssh2_wincng_pub_priv_write(unsigned char *key, - unsigned long offset, - const unsigned char *bignum, - const unsigned long length) -{ - _libssh2_htonu32(key + offset, length); - offset += 4; - - memcpy(key + offset, bignum, length); - offset += length; - - return offset; -} - -int -_libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session, - unsigned char **method, - size_t *method_len, - unsigned char **pubkeydata, - size_t *pubkeydata_len, - const char *privatekey, - const char *passphrase) -{ -#ifdef HAVE_LIBCRYPT32 - unsigned char *pbEncoded, **rpbDecoded; - unsigned long cbEncoded, *rcbDecoded; - unsigned char *key, *mth; - unsigned long keylen, mthlen, index, offset, length; - int ret; - - ret = _libssh2_wincng_load_private(session, privatekey, passphrase, - &pbEncoded, &cbEncoded); - if (ret) { - return -1; - } - - ret = _libssh2_wincng_asn_decode_bns(pbEncoded, cbEncoded, - &rpbDecoded, &rcbDecoded, &length); - - _libssh2_wincng_mfree(pbEncoded, cbEncoded); - - if (ret) { - return -1; - } - - - if (length == 9) { /* private RSA key */ - mthlen = 7; - mth = LIBSSH2_ALLOC(session, mthlen); - if (mth) { - memcpy(mth, "ssh-rsa", mthlen); - } else { - ret = -1; - } - - - keylen = 4 + mthlen + 4 + rcbDecoded[2] + 4 + rcbDecoded[1]; - key = LIBSSH2_ALLOC(session, keylen); - if (key) { - offset = _libssh2_wincng_pub_priv_write(key, 0, mth, mthlen); - - offset = _libssh2_wincng_pub_priv_write(key, offset, - rpbDecoded[2], - rcbDecoded[2]); - - _libssh2_wincng_pub_priv_write(key, offset, - rpbDecoded[1], - rcbDecoded[1]); - } else { - ret = -1; - } - - } else if (length == 6) { /* private DSA key */ - mthlen = 7; - mth = LIBSSH2_ALLOC(session, mthlen); - if (mth) { - memcpy(mth, "ssh-dss", mthlen); - } else { - ret = -1; - } - - keylen = 4 + mthlen + 4 + rcbDecoded[1] + 4 + rcbDecoded[2] - + 4 + rcbDecoded[3] + 4 + rcbDecoded[4]; - key = LIBSSH2_ALLOC(session, keylen); - if (key) { - offset = _libssh2_wincng_pub_priv_write(key, 0, mth, mthlen); - - offset = _libssh2_wincng_pub_priv_write(key, offset, - rpbDecoded[1], - rcbDecoded[1]); - - offset = _libssh2_wincng_pub_priv_write(key, offset, - rpbDecoded[2], - rcbDecoded[2]); - - offset = _libssh2_wincng_pub_priv_write(key, offset, - rpbDecoded[3], - rcbDecoded[3]); - - _libssh2_wincng_pub_priv_write(key, offset, - rpbDecoded[4], - rcbDecoded[4]); - } else { - ret = -1; - } - - } else { - ret = -1; - } - - - for (index = 0; index < length; index++) - _libssh2_wincng_mfree(rpbDecoded[index], rcbDecoded[index]); - - free(rpbDecoded); - free(rcbDecoded); - - - if (ret) { - if (mth) - LIBSSH2_FREE(session, mth); - if (key) - LIBSSH2_FREE(session, key); - } else { - *method = mth; - *method_len = mthlen; - *pubkeydata = key; - *pubkeydata_len = keylen; - } - - return ret; -#else - (void)method; - (void)method_len; - (void)pubkeydata; - (void)pubkeydata_len; - (void)privatekey; - (void)passphrase; - - return _libssh2_error(session, LIBSSH2_ERROR_FILE, - "Unable to load public key from private key file: " - "Method unsupported in Windows CNG backend"); -#endif /* HAVE_LIBCRYPT32 */ -} - - -/*******************************************************************/ -/* - * Windows CNG backend: Cipher functions - */ - -int -_libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx, - _libssh2_cipher_type(type), - unsigned char *iv, - unsigned char *secret, - int encrypt) -{ - BCRYPT_KEY_HANDLE hKey; - BCRYPT_KEY_DATA_BLOB_HEADER *header; - unsigned char *pbKeyObject, *pbIV, *key; - unsigned long dwKeyObject, dwIV, dwBlockLength, cbData, keylen; - int ret; - - (void)encrypt; - - ret = BCryptGetProperty(*type.phAlg, BCRYPT_OBJECT_LENGTH, - (unsigned char *)&dwKeyObject, - sizeof(dwKeyObject), - &cbData, 0); - if (ret != STATUS_SUCCESS) { - return -1; - } - - ret = BCryptGetProperty(*type.phAlg, BCRYPT_BLOCK_LENGTH, - (unsigned char *)&dwBlockLength, - sizeof(dwBlockLength), - &cbData, 0); - if (ret != STATUS_SUCCESS) { - return -1; - } - - pbKeyObject = malloc(dwKeyObject); - if (!pbKeyObject) { - return -1; - } - - - keylen = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + type.dwKeyLength; - key = malloc(keylen); - if (!key) { - free(pbKeyObject); - return -1; - } - - - header = (BCRYPT_KEY_DATA_BLOB_HEADER *)key; - header->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; - header->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; - header->cbKeyData = type.dwKeyLength; - - memcpy(key + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), - secret, type.dwKeyLength); - - ret = BCryptImportKey(*type.phAlg, NULL, BCRYPT_KEY_DATA_BLOB, &hKey, - pbKeyObject, dwKeyObject, key, keylen, 0); - - _libssh2_wincng_mfree(key, keylen); - - if (ret != STATUS_SUCCESS) { - _libssh2_wincng_mfree(pbKeyObject, dwKeyObject); - return -1; - } - - if (type.dwUseIV) { - pbIV = malloc(dwBlockLength); - if (!pbIV) { - BCryptDestroyKey(hKey); - _libssh2_wincng_mfree(pbKeyObject, dwKeyObject); - return -1; - } - dwIV = dwBlockLength; - memcpy(pbIV, iv, dwIV); - } else { - pbIV = NULL; - dwIV = 0; - } - - - ctx->hKey = hKey; - ctx->pbKeyObject = pbKeyObject; - ctx->pbIV = pbIV; - ctx->dwKeyObject = dwKeyObject; - ctx->dwIV = dwIV; - ctx->dwBlockLength = dwBlockLength; - - return 0; -} - -int -_libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, - _libssh2_cipher_type(type), - int encrypt, - unsigned char *block, - size_t blocklen) -{ - unsigned char *pbOutput; - unsigned long cbOutput; - int ret; - - (void)type; - - if (encrypt) { - ret = BCryptEncrypt(ctx->hKey, block, blocklen, NULL, - ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); - } else { - ret = BCryptDecrypt(ctx->hKey, block, blocklen, NULL, - ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); - } - if (ret == STATUS_SUCCESS) { - pbOutput = malloc(cbOutput); - if (pbOutput) { - if (encrypt) { - ret = BCryptEncrypt(ctx->hKey, block, blocklen, NULL, - ctx->pbIV, ctx->dwIV, - pbOutput, cbOutput, &cbOutput, 0); - } else { - ret = BCryptDecrypt(ctx->hKey, block, blocklen, NULL, - ctx->pbIV, ctx->dwIV, - pbOutput, cbOutput, &cbOutput, 0); - } - if (ret == STATUS_SUCCESS) { - memcpy(block, pbOutput, cbOutput); - } - - _libssh2_wincng_mfree(pbOutput, cbOutput); - } else - ret = STATUS_NO_MEMORY; - } - - return ret == STATUS_SUCCESS ? 0 : -1; -} - -void -_libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx) -{ - BCryptDestroyKey(ctx->hKey); - - _libssh2_wincng_mfree(ctx->pbKeyObject, ctx->dwKeyObject); - -#ifdef LIBSSH2_MEMORY_OVERWRITE - _libssh2_wincng_random(ctx, sizeof(_libssh2_cipher_ctx)); -#endif -} - - -/*******************************************************************/ -/* - * Windows CNG backend: BigNumber functions - */ - -_libssh2_bn * -_libssh2_wincng_bignum_init(void) -{ - _libssh2_bn *bignum; - - bignum = malloc(sizeof(_libssh2_bn)); - bignum->bignum = NULL; - bignum->length = 0; - - return bignum; -} - -static int -_libssh2_wincng_bignum_resize(_libssh2_bn *bn, unsigned long length) -{ - unsigned char *bignum; - - if (!bn) - return -1; - - if (length == bn->length) - return 0; - -#ifdef LIBSSH2_MEMORY_OVERWRITE - if (length == 0 && bn->bignum && bn->length > 0) { - _libssh2_wincng_mfree(bn->bignum, bn->length); - - bn->bignum = NULL; - bn->length = 0; - - return 0; - } - - bignum = malloc(length); - if (!bignum) - return -1; - - if (bn->bignum) { - memcpy(bignum, bn->bignum, min(length, bn->length)); - - _libssh2_wincng_mfree(bn->bignum, bn->length); - } - - bn->bignum = bignum; - bn->length = length; -#else - bignum = realloc(bn->bignum, length); - if (!bignum) - return -1; - - bn->bignum = bignum; - bn->length = length; -#endif - - return 0; -} - -int -_libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom) -{ - unsigned char *bignum; - unsigned long length; - - if (!rnd) - return -1; - - length = ceil((float)bits / 8) * sizeof(unsigned char); - if (_libssh2_wincng_bignum_resize(rnd, length)) - return -1; - - bignum = rnd->bignum; - - if (_libssh2_wincng_random(bignum, length)) - return -1; - - /* calculate significant bits in most significant byte */ - bits %= 8; - - /* fill most significant byte with zero padding */ - bignum[0] &= (1 << (8 - bits)) - 1; - - /* set some special last bits in most significant byte */ - if (top == 0) - bignum[0] |= (1 << (7 - bits)); - else if (top == 1) - bignum[0] |= (3 << (6 - bits)); - - /* make odd by setting first bit in least significant byte */ - if (bottom) - bignum[length - 1] |= 1; - - return 0; -} - -int -_libssh2_wincng_bignum_mod_exp(_libssh2_bn *r, - _libssh2_bn *a, - _libssh2_bn *p, - _libssh2_bn *m, - _libssh2_bn_ctx *bnctx) -{ - BCRYPT_KEY_HANDLE hKey; - BCRYPT_RSAKEY_BLOB *rsakey; - unsigned char *key, *bignum; - unsigned long keylen, offset, length; - int ret; - - (void)bnctx; - - if (!r || !a || !p || !m) - return -1; - - offset = sizeof(BCRYPT_RSAKEY_BLOB); - keylen = offset + p->length + m->length; - - key = malloc(keylen); - if (!key) - return -1; - - - /* http://msdn.microsoft.com/library/windows/desktop/aa375531.aspx */ - rsakey = (BCRYPT_RSAKEY_BLOB *)key; - rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; - rsakey->BitLength = m->length * 8; - rsakey->cbPublicExp = p->length; - rsakey->cbModulus = m->length; - rsakey->cbPrime1 = 0; - rsakey->cbPrime2 = 0; - - memcpy(key + offset, p->bignum, p->length); - offset += p->length; - - memcpy(key + offset, m->bignum, m->length); - - ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, - BCRYPT_RSAPUBLIC_BLOB, &hKey, key, keylen, - BCRYPT_NO_KEY_VALIDATION); - - if (ret == STATUS_SUCCESS) { - ret = BCryptEncrypt(hKey, a->bignum, a->length, NULL, NULL, 0, - NULL, 0, &length, BCRYPT_PAD_NONE); - if (ret == STATUS_SUCCESS) { - if (!_libssh2_wincng_bignum_resize(r, length)) { - length = max(a->length, length); - bignum = malloc(length); - if (bignum) { - offset = length - a->length; - memset(bignum, 0, offset); - memcpy(bignum + offset, a->bignum, a->length); - - ret = BCryptEncrypt(hKey, bignum, length, NULL, NULL, 0, - r->bignum, r->length, &offset, - BCRYPT_PAD_NONE); - - _libssh2_wincng_mfree(bignum, length); - - if (ret == STATUS_SUCCESS) { - _libssh2_wincng_bignum_resize(r, offset); - } - } else - ret = STATUS_NO_MEMORY; - } else - ret = STATUS_NO_MEMORY; - } - - BCryptDestroyKey(hKey); - } - - _libssh2_wincng_mfree(key, keylen); - - return ret == STATUS_SUCCESS ? 0 : -1; -} - -int -_libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word) -{ - unsigned long offset, number, bits, length; - - if (!bn) - return -1; - - number = word; - while (number >>= 1) - bits++; - - length = ceil((double)(bits+1) / 8) * sizeof(unsigned char); - if (_libssh2_wincng_bignum_resize(bn, length)) - return -1; - - for (offset = 0; offset < length; offset++) - bn->bignum[offset] = (word >> (offset * 8)) & 0xff; - - return 0; -} - -unsigned long -_libssh2_wincng_bignum_bits(const _libssh2_bn *bn) -{ - unsigned char number; - unsigned long offset, length, bits; - - if (!bn) - return 0; - - length = bn->length - 1; - - offset = 0; - while (!(*(bn->bignum + offset)) && (offset < length)) - offset++; - - bits = (length - offset) * 8; - number = bn->bignum[offset]; - - while (number >>= 1) - bits++; - - bits++; - - return bits; -} - -void -_libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, unsigned long len, - const unsigned char *bin) -{ - unsigned char *bignum; - unsigned long offset, length, bits; - - if (bn && bin && len > 0) { - if (!_libssh2_wincng_bignum_resize(bn, len)) { - memcpy(bn->bignum, bin, len); - - bits = _libssh2_wincng_bignum_bits(bn); - length = ceil((double)bits / 8) * sizeof(unsigned char); - - offset = bn->length - length; - if (offset > 0) { -#ifdef LIBSSH2_MEMORY_OVERWRITE - bignum = malloc(length); - if (bignum) { - memcpy(bignum, bn->bignum + offset, length); - - _libssh2_wincng_random(bn->bignum, bn->length); - - bn->bignum = bignum; - bn->length = length; - } -#else - memmove(bn->bignum, bn->bignum + offset, length); - - bignum = realloc(bn->bignum, length); - if (bignum) { - bn->bignum = bignum; - bn->length = length; - } -#endif - } - } - } -} - -void -_libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin) -{ - if (bin && bn && bn->bignum && bn->length > 0) { - memcpy(bin, bn->bignum, bn->length); - } -} - -void -_libssh2_wincng_bignum_free(_libssh2_bn *bn) -{ - if (bn) { - if (bn->bignum) { - _libssh2_wincng_mfree(bn->bignum, bn->length); - bn->bignum = NULL; - } - bn->length = 0; - free(bn); - } -} - - -/* - * Windows CNG backend: other functions - */ - -void _libssh2_init_aes_ctr(void) -{ - /* no implementation */ - (void)0; -} - -#endif /* LIBSSH2_WINCNG */ diff --git a/src/wincng.h b/src/wincng.h deleted file mode 100644 index a327b55..0000000 --- a/src/wincng.h +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 2013 Marc Hoersken - * All rights reserved. - * - * Redistribution and use in source and binary forms, - * with or without modification, are permitted provided - * that the following conditions are met: - * - * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * - * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Neither the name of the copyright holder nor the names - * of any other contributors may be used to endorse or - * promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 - -#ifdef HAVE_WINDOWS_H -#include -#endif -#ifdef HAVE_NTDEF_H -#include -#endif -#ifdef HAVE_NTSTATUS_H -#include -#endif - -#include - - -#define LIBSSH2_MD5 1 - -#define LIBSSH2_HMAC_RIPEMD 0 - -#define LIBSSH2_AES 1 -#define LIBSSH2_AES_CTR 0 -#define LIBSSH2_BLOWFISH 0 -#define LIBSSH2_RC4 1 -#define LIBSSH2_CAST 0 -#define LIBSSH2_3DES 1 - -#define LIBSSH2_RSA 1 -#define LIBSSH2_DSA 1 - -#define MD5_DIGEST_LENGTH 16 -#define SHA_DIGEST_LENGTH 20 - - -/*******************************************************************/ -/* - * Windows CNG backend: Global context handles - */ - -struct _libssh2_wincng_ctx { - BCRYPT_ALG_HANDLE hAlgRNG; - BCRYPT_ALG_HANDLE hAlgHashMD5; - BCRYPT_ALG_HANDLE hAlgHashSHA1; - BCRYPT_ALG_HANDLE hAlgHmacMD5; - BCRYPT_ALG_HANDLE hAlgHmacSHA1; - BCRYPT_ALG_HANDLE hAlgRSA; - BCRYPT_ALG_HANDLE hAlgDSA; - BCRYPT_ALG_HANDLE hAlgAES_CBC; - BCRYPT_ALG_HANDLE hAlgRC4_NA; - BCRYPT_ALG_HANDLE hAlg3DES_CBC; -}; - -struct _libssh2_wincng_ctx _libssh2_wincng; - - -/*******************************************************************/ -/* - * Windows CNG backend: Generic functions - */ - -void _libssh2_wincng_init(void); -void _libssh2_wincng_free(void); - -#define libssh2_crypto_init() \ - _libssh2_wincng_init() -#define libssh2_crypto_exit() \ - _libssh2_wincng_free() - -#define _libssh2_random(buf, len) \ - _libssh2_wincng_random(buf, len) - - -/*******************************************************************/ -/* - * Windows CNG backend: Hash structure - */ - -struct _libssh2_wincng_hash_ctx { - BCRYPT_HASH_HANDLE hHash; - unsigned char *pbHashObject; - unsigned long dwHashObject; - unsigned long cbHash; -}; - -#define _libssh2_wincng_hash_ctx struct _libssh2_wincng_hash_ctx - -/* - * Windows CNG backend: Hash functions - */ - -#define libssh2_sha1_ctx _libssh2_wincng_hash_ctx -#define libssh2_sha1_init(ctx) \ - _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \ - SHA_DIGEST_LENGTH, NULL, 0) -#define libssh2_sha1_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, data, datalen) -#define libssh2_sha1_final(ctx, hash) \ - _libssh2_wincng_hash_final(&ctx, hash) -#define libssh2_sha1(data, datalen, hash) \ - _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA1, \ - hash, SHA_DIGEST_LENGTH) - -#define libssh2_md5_ctx _libssh2_wincng_hash_ctx -#define libssh2_md5_init(ctx) \ - _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \ - MD5_DIGEST_LENGTH, NULL, 0) -#define libssh2_md5_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, data, datalen) -#define libssh2_md5_final(ctx, hash) \ - _libssh2_wincng_hash_final(&ctx, hash) -#define libssh2_md5(data, datalen, hash) \ - _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashMD5, \ - hash, MD5_DIGEST_LENGTH) - -/* - * Windows CNG backend: HMAC functions - */ - -#define libssh2_hmac_ctx _libssh2_wincng_hash_ctx -#define libssh2_hmac_sha1_init(ctx, key, keylen) \ - _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA1, \ - SHA_DIGEST_LENGTH, key, keylen) -#define libssh2_hmac_md5_init(ctx, key, keylen) \ - _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacMD5, \ - MD5_DIGEST_LENGTH, key, keylen) -#define libssh2_hmac_ripemd160_init(ctx, key, keylen) - /* not implemented */ -#define libssh2_hmac_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, data, datalen) -#define libssh2_hmac_final(ctx, hash) \ - _libssh2_wincng_hmac_final(&ctx, hash) -#define libssh2_hmac_cleanup(ctx) \ - _libssh2_wincng_hmac_cleanup(ctx) - - -/*******************************************************************/ -/* - * Windows CNG backend: Key Context structure - */ - -struct _libssh2_wincng_key_ctx { - BCRYPT_KEY_HANDLE hKey; - unsigned char *pbKeyObject; - unsigned long cbKeyObject; -}; - -#define _libssh2_wincng_key_ctx struct _libssh2_wincng_key_ctx - -/* - * Windows CNG backend: RSA functions - */ - -#define libssh2_rsa_ctx _libssh2_wincng_key_ctx -#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \ - d, d_len, p, p_len, q, q_len, \ - e1, e1_len, e2, e2_len, c, c_len) \ - _libssh2_wincng_rsa_new(rsactx, e, e_len, n, n_len, \ - d, d_len, p, p_len, q, q_len, \ - e1, e1_len, e2, e2_len, c, c_len) -#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \ - _libssh2_wincng_rsa_new_private(rsactx, s, filename, passphrase) -#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \ - _libssh2_wincng_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) -#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \ - _libssh2_wincng_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) -#define _libssh2_rsa_free(rsactx) \ - _libssh2_wincng_rsa_free(rsactx) - -/* - * Windows CNG backend: DSA functions - */ - -#define libssh2_dsa_ctx _libssh2_wincng_key_ctx -#define _libssh2_dsa_new(dsactx, p, p_len, q, q_len, \ - g, g_len, y, y_len, x, x_len) \ - _libssh2_wincng_dsa_new(dsactx, p, p_len, q, q_len, \ - g, g_len, y, y_len, x, x_len) -#define _libssh2_dsa_new_private(rsactx, s, filename, passphrase) \ - _libssh2_wincng_dsa_new_private(rsactx, s, filename, passphrase) -#define _libssh2_dsa_sha1_sign(dsactx, hash, hash_len, sig) \ - _libssh2_wincng_dsa_sha1_sign(dsactx, hash, hash_len, sig) -#define _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len) \ - _libssh2_wincng_dsa_sha1_verify(dsactx, sig, m, m_len) -#define _libssh2_dsa_free(dsactx) \ - _libssh2_wincng_dsa_free(dsactx) - -/* - * Windows CNG backend: Key functions - */ - -#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \ - _libssh2_wincng_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) - - -/*******************************************************************/ -/* - * Windows CNG backend: Cipher Context structure - */ - -struct _libssh2_wincng_cipher_ctx { - BCRYPT_KEY_HANDLE hKey; - unsigned char *pbKeyObject; - unsigned char *pbIV; - unsigned long dwKeyObject; - unsigned long dwIV; - unsigned long dwBlockLength; -}; - -#define _libssh2_cipher_ctx struct _libssh2_wincng_cipher_ctx - -/* - * Windows CNG backend: Cipher Type structure - */ - -struct _libssh2_wincng_cipher_type { - BCRYPT_ALG_HANDLE *phAlg; - unsigned long dwKeyLength; - unsigned long dwUseIV; -}; - -#define _libssh2_cipher_type(type) struct _libssh2_wincng_cipher_type type - -#define _libssh2_cipher_aes256ctr { NULL, 32, 1 } /* not supported */ -#define _libssh2_cipher_aes192ctr { NULL, 24, 1 } /* not supported */ -#define _libssh2_cipher_aes128ctr { NULL, 16, 1 } /* not supported */ -#define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1 } -#define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1 } -#define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1 } -#define _libssh2_cipher_blowfish { NULL, 16, 0 } /* not supported */ -#define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0 } -#define _libssh2_cipher_cast5 { NULL, 16, 0 } /* not supported */ -#define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1 } - -/* - * Windows CNG backend: Cipher functions - */ - -#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \ - _libssh2_wincng_cipher_init(ctx, type, iv, secret, encrypt) -#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen) \ - _libssh2_wincng_cipher_crypt(ctx, type, encrypt, block, blocklen) -#define _libssh2_cipher_dtor(ctx) \ - _libssh2_wincng_cipher_dtor(ctx) - -/*******************************************************************/ -/* - * Windows CNG backend: BigNumber Context - */ - -#define _libssh2_bn_ctx int /* not used */ -#define _libssh2_bn_ctx_new() 0 /* not used */ -#define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */ - - -/*******************************************************************/ -/* - * Windows CNG backend: BigNumber structure - */ - -struct _libssh2_wincng_bignum { - unsigned char *bignum; - unsigned long length; -}; - -#define _libssh2_bn struct _libssh2_wincng_bignum - -/* - * Windows CNG backend: BigNumber functions - */ - -_libssh2_bn *_libssh2_wincng_bignum_init(void); - -#define _libssh2_bn_init() \ - _libssh2_wincng_bignum_init() -#define _libssh2_bn_rand(bn, bits, top, bottom) \ - _libssh2_wincng_bignum_rand(bn, bits, top, bottom) -#define _libssh2_bn_mod_exp(r, a, p, m, ctx) \ - _libssh2_wincng_bignum_mod_exp(r, a, p, m, ctx) -#define _libssh2_bn_set_word(bn, word) \ - _libssh2_wincng_bignum_set_word(bn, word) -#define _libssh2_bn_from_bin(bn, len, bin) \ - _libssh2_wincng_bignum_from_bin(bn, len, bin) -#define _libssh2_bn_to_bin(bn, bin) \ - _libssh2_wincng_bignum_to_bin(bn, bin) -#define _libssh2_bn_bytes(bn) bn->length -#define _libssh2_bn_bits(bn) \ - _libssh2_wincng_bignum_bits(bn) -#define _libssh2_bn_free(bn) \ - _libssh2_wincng_bignum_free(bn)