summaryrefslogtreecommitdiff
path: root/src/mscrypto/crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscrypto/crypto.c')
-rw-r--r--src/mscrypto/crypto.c413
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));
}
/********************************************************************