diff options
Diffstat (limited to 'src/mscrypto/crypto.c')
-rw-r--r-- | src/mscrypto/crypto.c | 413 |
1 files changed, 105 insertions, 308 deletions
diff --git a/src/mscrypto/crypto.c b/src/mscrypto/crypto.c index aea9685e..72473a4b 100644 --- a/src/mscrypto/crypto.c +++ b/src/mscrypto/crypto.c @@ -1,5 +1,6 @@ -/** - * XMLSec library +/* + * XML Security Library (http://www.aleksey.com/xmlsec). + * * * This is free software; see Copyright file in the source * distribution for preciese wording. @@ -8,6 +9,13 @@ * Copyright (C) 2003-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. * Copyright (c) 2005-2006 Cryptocom LTD (http://www.cryptocom.ru). */ +/** + * SECTION:crypto + * @Short_description: Crypto transforms implementation for Microsoft Crypto API. + * @Stability: Stable + * + */ + #include "globals.h" #include <string.h> @@ -25,36 +33,14 @@ #include <xmlsec/mscrypto/x509.h> #include "private.h" -#if defined(__MINGW32__) -/* NOTE mingw.org project don't define any xxx_s function and may - * be never will define them. - * - * In this file is save to use non _s function as into destination - * buffer program code copy empty string and the size of source buffer - * (XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE=4096) is enough for any - * encoding. Also program code don't check result of _s functions. - */ - -static int -strcpy_s(char *dest, size_t n, const char *src) { - strcpy(dest, src); - return(0); -} - -static int -wcscpy_s(wchar_t *dest, size_t n, const wchar_t *src) { - wcscpy(dest, src); - return(0); -} -#endif #define XMLSEC_CONTAINER_NAME_A "xmlsec-key-container" #define XMLSEC_CONTAINER_NAME_W L"xmlsec-key-container" #ifdef UNICODE #define XMLSEC_CONTAINER_NAME XMLSEC_CONTAINER_NAME_W -#else +#else /* UNICODE */ #define XMLSEC_CONTAINER_NAME XMLSEC_CONTAINER_NAME_A -#endif +#endif /* UNICODE */ static xmlSecCryptoDLFunctionsPtr gXmlSecMSCryptoFunctions = NULL; @@ -115,6 +101,11 @@ xmlSecCryptoGetFunctions_mscrypto(void) { gXmlSecMSCryptoFunctions->keyDataGost2001GetKlass = xmlSecMSCryptoKeyDataGost2001GetKlass; #endif /* XMLSEC_NO_GOST*/ +#ifndef XMLSEC_NO_GOST2012 + gXmlSecMSCryptoFunctions->keyDataGostR3410_2012_256GetKlass = xmlSecMSCryptoKeyDataGost2012_256GetKlass; + gXmlSecMSCryptoFunctions->keyDataGostR3410_2012_512GetKlass = xmlSecMSCryptoKeyDataGost2012_512GetKlass; +#endif /* XMLSEC_NO_GOST2012*/ + #ifndef XMLSEC_NO_X509 gXmlSecMSCryptoFunctions->keyDataX509GetKlass = xmlSecMSCryptoKeyDataX509GetKlass; gXmlSecMSCryptoFunctions->keyDataRawX509CertGetKlass = xmlSecMSCryptoKeyDataRawX509CertGetKlass; @@ -161,6 +152,14 @@ xmlSecCryptoGetFunctions_mscrypto(void) { gXmlSecMSCryptoFunctions->transformGost2001GostR3411_94GetKlass = xmlSecMSCryptoTransformGost2001GostR3411_94GetKlass; #endif /* XMLSEC_NO_GOST */ +#ifndef XMLSEC_NO_GOST2012 + gXmlSecMSCryptoFunctions->transformGostR3411_2012_256GetKlass = xmlSecMSCryptoTransformGostR3411_2012_256GetKlass; + gXmlSecMSCryptoFunctions->transformGostR3410_2012GostR3411_2012_256GetKlass = xmlSecMSCryptoTransformGost2012_256GetKlass; + + gXmlSecMSCryptoFunctions->transformGostR3411_2012_512GetKlass = xmlSecMSCryptoTransformGostR3411_2012_512GetKlass; + gXmlSecMSCryptoFunctions->transformGostR3410_2012GostR3411_2012_512GetKlass = xmlSecMSCryptoTransformGost2012_512GetKlass; +#endif /* XMLSEC_NO_GOST2012 */ + #ifndef XMLSEC_NO_GOST gXmlSecMSCryptoFunctions->transformGostR3411_94GetKlass = xmlSecMSCryptoTransformGostR3411_94GetKlass; #endif /* XMLSEC_NO_GOST */ @@ -273,11 +272,7 @@ int xmlSecMSCryptoInit (void) { /* Check loaded xmlsec library version */ if(xmlSecCheckVersionExact() != 1) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecCheckVersionExact", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecCheckVersionExact", NULL); return(-1); } @@ -286,11 +281,7 @@ xmlSecMSCryptoInit (void) { /* register our klasses */ if(xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms(xmlSecCryptoGetFunctions_mscrypto()) < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms", NULL); return(-1); } return(0); @@ -330,21 +321,13 @@ xmlSecMSCryptoKeysMngrInit(xmlSecKeysMngrPtr mngr) { x509Store = xmlSecKeyDataStoreCreate(xmlSecMSCryptoX509StoreId); if(x509Store == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeyDataStoreCreate", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "xmlSecMSCryptoX509StoreId"); + xmlSecInternalError("xmlSecKeyDataStoreCreate(xmlSecMSCryptoX509StoreId)", NULL); return(-1); } ret = xmlSecKeysMngrAdoptDataStore(mngr, x509Store); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecKeysMngrAdoptDataStore", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecKeysMngrAdoptDataStore", NULL); xmlSecKeyDataStoreDestroy(x509Store); return(-1); } @@ -354,7 +337,6 @@ xmlSecMSCryptoKeysMngrInit(xmlSecKeysMngrPtr mngr) { return(0); } - static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Random[] = { { MS_STRONG_PROV, PROV_RSA_FULL }, { MS_ENHANCED_PROV, PROV_RSA_FULL }, @@ -372,7 +354,7 @@ static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Random[] = { * Returns: 0 on success or a negative value otherwise. */ int -xmlSecMSCryptoGenerateRandom(xmlSecBufferPtr buffer, size_t size) { +xmlSecMSCryptoGenerateRandom(xmlSecBufferPtr buffer, xmlSecSize size) { HCRYPTPROV hProv = 0; int ret; @@ -381,29 +363,18 @@ xmlSecMSCryptoGenerateRandom(xmlSecBufferPtr buffer, size_t size) { ret = xmlSecBufferSetSize(buffer, size); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecBufferSetSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", size); + xmlSecInternalError2("xmlSecBufferSetSize", NULL, + "size=%d", size); return(-1); } hProv = xmlSecMSCryptoFindProvider(xmlSecMSCryptoProviderInfo_Random, NULL, CRYPT_VERIFYCONTEXT, FALSE); if (0 == hProv) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecMSCryptoFindProvider", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecMSCryptoFindProvider", NULL); return(-1); } if (FALSE == CryptGenRandom(hProv, (DWORD)size, xmlSecBufferGetData(buffer))) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "CryptGenRandom", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecMSCryptoError("CryptGenRandom", NULL); CryptReleaseContext(hProv,0); return(-1); } @@ -412,71 +383,85 @@ xmlSecMSCryptoGenerateRandom(xmlSecBufferPtr buffer, size_t size) { return(0); } -#define XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE 4096 - /** - * xmlSecMSCryptoErrorsDefaultCallback: - * @file: the error location file name (__FILE__ macro). - * @line: the error location line number (__LINE__ macro). - * @func: the error location function name (__FUNCTION__ macro). - * @errorObject: the error specific error object - * @errorSubject: the error specific error subject. - * @reason: the error code. - * @msg: the additional error message. + * xmlSecMSCryptoGetErrorMessage: + * @dwError: the error code. + * @out: the output buffer. + * $outSize: the output buffer size. * - * The default errors reporting callback function. + * Returns the system error message for the give error code. */ void -xmlSecMSCryptoErrorsDefaultCallback(const char* file, int line, const char* func, - const char* errorObject, const char* errorSubject, - int reason, const char* msg) { - DWORD dwError; - TCHAR errorT[XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE]; - WCHAR errorW[XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE]; - CHAR errorUTF8[XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE]; - xmlChar buf[XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE]; - DWORD rc; - int ret; +xmlSecMSCryptoGetErrorMessage(DWORD dwError, xmlChar * out, xmlSecSize outSize) { + LPTSTR errorText = NULL; + DWORD ret; +#ifndef UNICODE + WCHAR errorTextW[XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE]; +#endif /* UNICODE */ - dwError = GetLastError(); - rc = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dwError, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ - errorT, - XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE, - NULL); - -#ifdef UNICODE - if(rc <= 0) { - wcscpy_s(errorT, XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE, L""); + xmlSecAssert(out != NULL); + xmlSecAssert(outSize > 0); + + /* Use system message tables to retrieve error text, allocate buffer on local + heap for error text, don't use any inserts/parameters */ + ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dwError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + (LPTSTR)&errorText, + 0, + NULL); + if((ret <= 0) || (errorText == NULL)) { + out[0] = '\0'; + goto done; } - ret = WideCharToMultiByte(CP_UTF8, 0, errorT, -1, errorUTF8, XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE, NULL, NULL); + +#ifdef UNICODE + ret = WideCharToMultiByte(CP_UTF8, 0, errorText, -1, (LPSTR)out, outSize, NULL, NULL); if(ret <= 0) { - strcpy_s(errorUTF8, XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE, ""); + out[0] = '\0'; + goto done; } #else /* UNICODE */ - if(rc <= 0) { - strcpy_s(errorT, XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE, ""); - } - ret = MultiByteToWideChar(CP_ACP, 0, errorT, -1, errorW, XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE); + ret = MultiByteToWideChar(CP_ACP, 0, errorText, -1, errorTextW, XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE); if(ret <= 0) { - wcscpy_s(errorW, XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE, L""); + out[0] = '\0'; + goto done; } - ret = WideCharToMultiByte(CP_UTF8, 0, errorW, -1, errorUTF8, XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE, NULL, NULL); + ret = WideCharToMultiByte(CP_UTF8, 0, errorTextW, -1, (LPSTR)out, outSize, NULL, NULL); if(ret <= 0) { - strcpy_s(errorUTF8, XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE, ""); + out[0] = '\0'; + goto done; } #endif /* UNICODE */ - if((msg != NULL) && ((*msg) != '\0')) { - xmlSecStrPrintf(buf, sizeof(buf), BAD_CAST "%s;last error=%d (0x%08x);last error msg=%s", msg, dwError, dwError, errorUTF8); - } else { - xmlSecStrPrintf(buf, sizeof(buf), BAD_CAST "last error=%d (0x%08x);last error msg=%s", dwError, dwError, errorUTF8); +done: + if(errorText != NULL) { + LocalFree(errorText); } - xmlSecErrorsDefaultCallback(file, line, func, - errorObject, errorSubject, - reason, (char*)buf); + return; +} + + +/** + * xmlSecMSCryptoErrorsDefaultCallback: + * @file: the error location file name (__FILE__ macro). + * @line: the error location line number (__LINE__ macro). + * @func: the error location function name (__FUNCTION__ macro). + * @errorObject: the error specific error object + * @errorSubject: the error specific error subject. + * @reason: the error code. + * @msg: the additional error message. + * + * The default errors reporting callback function. Just a pass through to the default callback. + */ +void +xmlSecMSCryptoErrorsDefaultCallback(const char* file, int line, const char* func, + const char* errorObject, const char* errorSubject, + int reason, const char* msg) { + xmlSecErrorsDefaultCallback(file, line, func, errorObject, errorSubject, reason, msg); } /** @@ -489,39 +474,7 @@ xmlSecMSCryptoErrorsDefaultCallback(const char* file, int line, const char* func */ LPWSTR xmlSecMSCryptoConvertUtf8ToUnicode(const xmlChar* str) { - LPWSTR res = NULL; - int len; - int ret; - - xmlSecAssert2(str != NULL, NULL); - - /* call MultiByteToWideChar first to get the buffer size */ - ret = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); - if(ret <= 0) { - return(NULL); - } - len = ret + 1; - - /* allocate buffer */ - res = (LPWSTR)xmlMalloc(sizeof(WCHAR) * len); - if(res == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_MALLOC_FAILED, - "size=%d", sizeof(WCHAR) * len); - return(NULL); - } - - /* convert */ - ret = MultiByteToWideChar(CP_UTF8, 0, str, -1, res, len); - if(ret <= 0) { - xmlFree(res); - return(NULL); - } - - /* done */ - return(res); + return(xmlSecWin32ConvertUtf8ToUnicode(str)); } /** @@ -532,41 +485,9 @@ xmlSecMSCryptoConvertUtf8ToUnicode(const xmlChar* str) { * * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs. */ -xmlChar* +xmlChar* xmlSecMSCryptoConvertUnicodeToUtf8(LPCWSTR str) { - xmlChar * res = NULL; - int len; - int ret; - - xmlSecAssert2(str != NULL, NULL); - - /* call WideCharToMultiByte first to get the buffer size */ - ret = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL); - if(ret <= 0) { - return(NULL); - } - len = ret + 1; - - /* allocate buffer */ - res = (xmlChar*)xmlMalloc(sizeof(xmlChar) * len); - if(res == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_MALLOC_FAILED, - "size=%d", sizeof(xmlChar) * len); - return(NULL); - } - - /* convert */ - ret = WideCharToMultiByte(CP_UTF8, 0, str, -1, res, len, NULL, NULL); - if(ret <= 0) { - xmlFree(res); - return(NULL); - } - - /* done */ - return(res); + return(xmlSecWin32ConvertUnicodeToUtf8(str)); } /** @@ -579,39 +500,7 @@ xmlSecMSCryptoConvertUnicodeToUtf8(LPCWSTR str) { */ LPWSTR xmlSecMSCryptoConvertLocaleToUnicode(const char* str) { - LPWSTR res = NULL; - int len; - int ret; - - xmlSecAssert2(str != NULL, NULL); - - /* call MultiByteToWideChar first to get the buffer size */ - ret = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); - if(ret <= 0) { - return(NULL); - } - len = ret; - - /* allocate buffer */ - res = (LPWSTR)xmlMalloc(sizeof(WCHAR) * len); - if(res == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_MALLOC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - return(NULL); - } - - /* convert */ - ret = MultiByteToWideChar(CP_ACP, 0, str, -1, res, len); - if(ret <= 0) { - xmlFree(res); - return(NULL); - } - - /* done */ - return(res); + return(xmlSecWin32ConvertLocaleToUnicode(str)); } /** @@ -624,49 +513,7 @@ xmlSecMSCryptoConvertLocaleToUnicode(const char* str) { */ xmlChar* xmlSecMSCryptoConvertLocaleToUtf8(const char * str) { - LPWSTR strW = NULL; - xmlChar * res = NULL; - int len; - int ret; - - xmlSecAssert2(str != NULL, NULL); - - strW = xmlSecMSCryptoConvertLocaleToUnicode(str); - if(strW == NULL) { - return(NULL); - } - - /* call WideCharToMultiByte first to get the buffer size */ - ret = WideCharToMultiByte(CP_ACP, 0, strW, -1, NULL, 0, NULL, NULL); - if(ret <= 0) { - xmlFree(strW); - return(NULL); - } - len = ret + 1; - - /* allocate buffer */ - res = (xmlChar*)xmlMalloc(sizeof(xmlChar) * len); - if(res == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_MALLOC_FAILED, - "size=%d", sizeof(xmlChar) * len); - xmlFree(strW); - return(NULL); - } - - /* convert */ - ret = WideCharToMultiByte(CP_ACP, 0, strW, -1, res, len, NULL, NULL); - if(ret <= 0) { - xmlFree(strW); - xmlFree(res); - return(NULL); - } - - /* done */ - xmlFree(strW); - return(res); + return(xmlSecWin32ConvertLocaleToUtf8(str)); } /** @@ -679,49 +526,7 @@ xmlSecMSCryptoConvertLocaleToUtf8(const char * str) { */ char * xmlSecMSCryptoConvertUtf8ToLocale(const xmlChar* str) { - LPWSTR strW = NULL; - char * res = NULL; - int len; - int ret; - - xmlSecAssert2(str != NULL, NULL); - - strW = xmlSecMSCryptoConvertUtf8ToUnicode(str); - if(strW == NULL) { - return(NULL); - } - - /* call WideCharToMultiByte first to get the buffer size */ - ret = WideCharToMultiByte(CP_ACP, 0, strW, -1, NULL, 0, NULL, NULL); - if(ret <= 0) { - xmlFree(strW); - return(NULL); - } - len = ret + 1; - - /* allocate buffer */ - res = (char*)xmlMalloc(sizeof(char) * len); - if(res == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_MALLOC_FAILED, - "size=%d", sizeof(xmlChar) * len); - xmlFree(strW); - return(NULL); - } - - /* convert */ - ret = WideCharToMultiByte(CP_ACP, 0, strW, -1, res, len, NULL, NULL); - if(ret <= 0) { - xmlFree(strW); - xmlFree(res); - return(NULL); - } - - /* done */ - xmlFree(strW); - return(res); + return(xmlSecWin32ConvertUtf8ToLocale(str)); } /** @@ -734,11 +539,7 @@ xmlSecMSCryptoConvertUtf8ToLocale(const xmlChar* str) { */ xmlChar* xmlSecMSCryptoConvertTstrToUtf8(LPCTSTR str) { -#ifdef UNICODE - return xmlSecMSCryptoConvertUnicodeToUtf8(str); -#else /* UNICODE */ - return xmlSecMSCryptoConvertLocaleToUtf8(str); -#endif /* UNICODE */ + return(xmlSecWin32ConvertTstrToUtf8(str)); } /** @@ -751,11 +552,7 @@ xmlSecMSCryptoConvertTstrToUtf8(LPCTSTR str) { */ LPTSTR xmlSecMSCryptoConvertUtf8ToTstr(const xmlChar* str) { -#ifdef UNICODE - return xmlSecMSCryptoConvertUtf8ToUnicode(str); -#else /* UNICODE */ - return xmlSecMSCryptoConvertUtf8ToLocale(str); -#endif /* UNICODE */ + return(xmlSecWin32ConvertUtf8ToTstr(str)); } /******************************************************************** |