1 /*
2  * XML Security Library (http://www.aleksey.com/xmlsec).
3  *
4  *
5  * This is free software; see Copyright file in the source
6  * distribution for preciese wording.
7  *
8  * Copyright (C) 2003 Cordys R&D BV, All rights reserved.
9  * Copyright (C) 2003-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
10  * Copyright (c) 2005-2006 Cryptocom LTD (http://www.cryptocom.ru).
11  */
12 /**
13  * SECTION:crypto
14  * @Short_description: Crypto transforms implementation for Microsoft Crypto API.
15  * @Stability: Stable
16  *
17  */
18 
19 #include "globals.h"
20 
21 #include <string.h>
22 
23 #include <xmlsec/xmlsec.h>
24 #include <xmlsec/keys.h>
25 #include <xmlsec/transforms.h>
26 #include <xmlsec/errors.h>
27 #include <xmlsec/dl.h>
28 #include <xmlsec/xmltree.h>
29 #include <xmlsec/private.h>
30 
31 #include <xmlsec/mscrypto/app.h>
32 #include <xmlsec/mscrypto/crypto.h>
33 #include <xmlsec/mscrypto/x509.h>
34 #include "private.h"
35 
36 
37 #define XMLSEC_CONTAINER_NAME_A "xmlsec-key-container"
38 #define XMLSEC_CONTAINER_NAME_W L"xmlsec-key-container"
39 #ifdef UNICODE
40 #define XMLSEC_CONTAINER_NAME XMLSEC_CONTAINER_NAME_W
41 #else /* UNICODE */
42 #define XMLSEC_CONTAINER_NAME XMLSEC_CONTAINER_NAME_A
43 #endif /* UNICODE */
44 
45 
46 static xmlSecCryptoDLFunctionsPtr gXmlSecMSCryptoFunctions = NULL;
47 
48 /**
49  * xmlSecCryptoGetFunctions_mscrypto:
50  *
51  * Gets MSCrypto specific functions table.
52  *
53  * Returns: xmlsec-mscrypto functions table.
54  */
55 xmlSecCryptoDLFunctionsPtr
xmlSecCryptoGetFunctions_mscrypto(void)56 xmlSecCryptoGetFunctions_mscrypto(void) {
57     static xmlSecCryptoDLFunctions functions;
58 
59     if(gXmlSecMSCryptoFunctions != NULL) {
60         return(gXmlSecMSCryptoFunctions);
61     }
62 
63     memset(&functions, 0, sizeof(functions));
64     gXmlSecMSCryptoFunctions = &functions;
65 
66     /********************************************************************
67      *
68      * Crypto Init/shutdown
69      *
70      ********************************************************************/
71     gXmlSecMSCryptoFunctions->cryptoInit                        = xmlSecMSCryptoInit;
72     gXmlSecMSCryptoFunctions->cryptoShutdown                    = xmlSecMSCryptoShutdown;
73     gXmlSecMSCryptoFunctions->cryptoKeysMngrInit                = xmlSecMSCryptoKeysMngrInit;
74 
75     /********************************************************************
76      *
77      * Key data ids
78      *
79      ********************************************************************/
80 #ifndef XMLSEC_NO_DES
81     gXmlSecMSCryptoFunctions->keyDataDesGetKlass                = xmlSecMSCryptoKeyDataDesGetKlass;
82 #endif /* XMLSEC_NO_DES */
83 
84 #ifndef XMLSEC_NO_AES
85     gXmlSecMSCryptoFunctions->keyDataAesGetKlass                = xmlSecMSCryptoKeyDataAesGetKlass;
86 #endif /* XMLSEC_NO_AES */
87 
88 #ifndef XMLSEC_NO_RSA
89     gXmlSecMSCryptoFunctions->keyDataRsaGetKlass                = xmlSecMSCryptoKeyDataRsaGetKlass;
90 #endif /* XMLSEC_NO_RSA */
91 
92 #ifndef XMLSEC_NO_HMAC
93     gXmlSecMSCryptoFunctions->keyDataHmacGetKlass               = xmlSecMSCryptoKeyDataHmacGetKlass;
94 #endif /* XMLSEC_NO_HMAC */
95 
96 #ifndef XMLSEC_NO_DSA
97     gXmlSecMSCryptoFunctions->keyDataDsaGetKlass                = xmlSecMSCryptoKeyDataDsaGetKlass;
98 #endif /* XMLSEC_NO_DSA */
99 
100 #ifndef XMLSEC_NO_GOST
101     gXmlSecMSCryptoFunctions->keyDataGost2001GetKlass           = xmlSecMSCryptoKeyDataGost2001GetKlass;
102 #endif /* XMLSEC_NO_GOST*/
103 
104 #ifndef XMLSEC_NO_GOST2012
105     gXmlSecMSCryptoFunctions->keyDataGostR3410_2012_256GetKlass = xmlSecMSCryptoKeyDataGost2012_256GetKlass;
106     gXmlSecMSCryptoFunctions->keyDataGostR3410_2012_512GetKlass = xmlSecMSCryptoKeyDataGost2012_512GetKlass;
107 #endif /* XMLSEC_NO_GOST2012*/
108 
109 #ifndef XMLSEC_NO_X509
110     gXmlSecMSCryptoFunctions->keyDataX509GetKlass               = xmlSecMSCryptoKeyDataX509GetKlass;
111     gXmlSecMSCryptoFunctions->keyDataRawX509CertGetKlass        = xmlSecMSCryptoKeyDataRawX509CertGetKlass;
112 #endif /* XMLSEC_NO_X509 */
113 
114     /********************************************************************
115      *
116      * Key data store ids
117      *
118      ********************************************************************/
119 #ifndef XMLSEC_NO_X509
120     gXmlSecMSCryptoFunctions->x509StoreGetKlass                 = xmlSecMSCryptoX509StoreGetKlass;
121 #endif /* XMLSEC_NO_X509 */
122 
123     /********************************************************************
124      *
125      * Crypto transforms ids
126      *
127      ********************************************************************/
128 
129     /******************************* AES ********************************/
130 #ifndef XMLSEC_NO_AES
131     gXmlSecMSCryptoFunctions->transformAes128CbcGetKlass        = xmlSecMSCryptoTransformAes128CbcGetKlass;
132     gXmlSecMSCryptoFunctions->transformAes192CbcGetKlass        = xmlSecMSCryptoTransformAes192CbcGetKlass;
133     gXmlSecMSCryptoFunctions->transformAes256CbcGetKlass        = xmlSecMSCryptoTransformAes256CbcGetKlass;
134     gXmlSecMSCryptoFunctions->transformKWAes128GetKlass         = xmlSecMSCryptoTransformKWAes128GetKlass;
135     gXmlSecMSCryptoFunctions->transformKWAes192GetKlass         = xmlSecMSCryptoTransformKWAes192GetKlass;
136     gXmlSecMSCryptoFunctions->transformKWAes256GetKlass         = xmlSecMSCryptoTransformKWAes256GetKlass;
137 #endif /* XMLSEC_NO_AES */
138 
139     /******************************* DES ********************************/
140 #ifndef XMLSEC_NO_DES
141     gXmlSecMSCryptoFunctions->transformDes3CbcGetKlass          = xmlSecMSCryptoTransformDes3CbcGetKlass;
142     gXmlSecMSCryptoFunctions->transformKWDes3GetKlass           = xmlSecMSCryptoTransformKWDes3GetKlass;
143 #endif /* XMLSEC_NO_DES */
144 
145     /******************************* DSA ********************************/
146 #ifndef XMLSEC_NO_DSA
147     gXmlSecMSCryptoFunctions->transformDsaSha1GetKlass          = xmlSecMSCryptoTransformDsaSha1GetKlass;
148 #endif /* XMLSEC_NO_DSA */
149 
150     /******************************* GOST ********************************/
151 #ifndef XMLSEC_NO_GOST
152     gXmlSecMSCryptoFunctions->transformGost2001GostR3411_94GetKlass             = xmlSecMSCryptoTransformGost2001GostR3411_94GetKlass;
153 #endif /* XMLSEC_NO_GOST */
154 
155 #ifndef XMLSEC_NO_GOST2012
156     gXmlSecMSCryptoFunctions->transformGostR3411_2012_256GetKlass               = xmlSecMSCryptoTransformGostR3411_2012_256GetKlass;
157     gXmlSecMSCryptoFunctions->transformGostR3410_2012GostR3411_2012_256GetKlass = xmlSecMSCryptoTransformGost2012_256GetKlass;
158 
159     gXmlSecMSCryptoFunctions->transformGostR3411_2012_512GetKlass               = xmlSecMSCryptoTransformGostR3411_2012_512GetKlass;
160     gXmlSecMSCryptoFunctions->transformGostR3410_2012GostR3411_2012_512GetKlass = xmlSecMSCryptoTransformGost2012_512GetKlass;
161 #endif /* XMLSEC_NO_GOST2012 */
162 
163 #ifndef XMLSEC_NO_GOST
164     gXmlSecMSCryptoFunctions->transformGostR3411_94GetKlass             = xmlSecMSCryptoTransformGostR3411_94GetKlass;
165 #endif /* XMLSEC_NO_GOST */
166 
167     /******************************* HMAC ********************************/
168 #ifndef XMLSEC_NO_HMAC
169 
170 #ifndef XMLSEC_NO_MD5
171     gXmlSecMSCryptoFunctions->transformHmacMd5GetKlass         = xmlSecMSCryptoTransformHmacMd5GetKlass;
172 #endif /* XMLSEC_NO_MD5 */
173 
174 #ifndef XMLSEC_NO_SHA1
175     gXmlSecMSCryptoFunctions->transformHmacSha1GetKlass        = xmlSecMSCryptoTransformHmacSha1GetKlass;
176 #endif /* XMLSEC_NO_SHA1 */
177 
178 #ifndef XMLSEC_NO_SHA256
179     gXmlSecMSCryptoFunctions->transformHmacSha256GetKlass      = xmlSecMSCryptoTransformHmacSha256GetKlass;
180 #endif /* XMLSEC_NO_SHA256 */
181 
182 #ifndef XMLSEC_NO_SHA384
183     gXmlSecMSCryptoFunctions->transformHmacSha384GetKlass      = xmlSecMSCryptoTransformHmacSha384GetKlass;
184 #endif /* XMLSEC_NO_SHA384 */
185 
186 #ifndef XMLSEC_NO_SHA512
187     gXmlSecMSCryptoFunctions->transformHmacSha512GetKlass      = xmlSecMSCryptoTransformHmacSha512GetKlass;
188 #endif /* XMLSEC_NO_SHA512 */
189 
190 #endif /* XMLSEC_NO_HMAC */
191 
192     /******************************* MD5 ********************************/
193 #ifndef XMLSEC_NO_MD5
194     gXmlSecMSCryptoFunctions->transformMd5GetKlass             = xmlSecMSCryptoTransformMd5GetKlass;
195 #endif /* XMLSEC_NO_MD5 */
196 
197     /******************************* RSA ********************************/
198 #ifndef XMLSEC_NO_RSA
199 
200 #ifndef XMLSEC_NO_MD5
201     gXmlSecMSCryptoFunctions->transformRsaMd5GetKlass          = xmlSecMSCryptoTransformRsaMd5GetKlass;
202 #endif /* XMLSEC_NO_MD5 */
203 
204 #ifndef XMLSEC_NO_SHA1
205     gXmlSecMSCryptoFunctions->transformRsaSha1GetKlass          = xmlSecMSCryptoTransformRsaSha1GetKlass;
206 #endif /* XMLSEC_NO_SHA1 */
207 
208 #ifndef XMLSEC_NO_SHA256
209     gXmlSecMSCryptoFunctions->transformRsaSha256GetKlass       = xmlSecMSCryptoTransformRsaSha256GetKlass;
210 #endif /* XMLSEC_NO_SHA256 */
211 
212 #ifndef XMLSEC_NO_SHA384
213     gXmlSecMSCryptoFunctions->transformRsaSha384GetKlass       = xmlSecMSCryptoTransformRsaSha384GetKlass;
214 #endif /* XMLSEC_NO_SHA384 */
215 
216 #ifndef XMLSEC_NO_SHA512
217     gXmlSecMSCryptoFunctions->transformRsaSha512GetKlass       = xmlSecMSCryptoTransformRsaSha512GetKlass;
218 #endif /* XMLSEC_NO_SHA512 */
219 
220     gXmlSecMSCryptoFunctions->transformRsaPkcs1GetKlass         = xmlSecMSCryptoTransformRsaPkcs1GetKlass;
221     gXmlSecMSCryptoFunctions->transformRsaOaepGetKlass          = xmlSecMSCryptoTransformRsaOaepGetKlass;
222 #endif /* XMLSEC_NO_RSA */
223 
224     /******************************* SHA ********************************/
225 #ifndef XMLSEC_NO_SHA1
226     gXmlSecMSCryptoFunctions->transformSha1GetKlass             = xmlSecMSCryptoTransformSha1GetKlass;
227 #endif /* XMLSEC_NO_SHA1 */
228 #ifndef XMLSEC_NO_SHA256
229     gXmlSecMSCryptoFunctions->transformSha256GetKlass          = xmlSecMSCryptoTransformSha256GetKlass;
230 #endif /* XMLSEC_NO_SHA256 */
231 #ifndef XMLSEC_NO_SHA384
232     gXmlSecMSCryptoFunctions->transformSha384GetKlass          = xmlSecMSCryptoTransformSha384GetKlass;
233 #endif /* XMLSEC_NO_SHA384 */
234 #ifndef XMLSEC_NO_SHA512
235     gXmlSecMSCryptoFunctions->transformSha512GetKlass          = xmlSecMSCryptoTransformSha512GetKlass;
236 #endif /* XMLSEC_NO_SHA512 */
237 
238     /********************************************************************
239      *
240      * High level routines form xmlsec command line utility
241      *
242      ********************************************************************/
243     gXmlSecMSCryptoFunctions->cryptoAppInit                     = xmlSecMSCryptoAppInit;
244     gXmlSecMSCryptoFunctions->cryptoAppShutdown                 = xmlSecMSCryptoAppShutdown;
245     gXmlSecMSCryptoFunctions->cryptoAppDefaultKeysMngrInit      = xmlSecMSCryptoAppDefaultKeysMngrInit;
246     gXmlSecMSCryptoFunctions->cryptoAppDefaultKeysMngrAdoptKey  = xmlSecMSCryptoAppDefaultKeysMngrAdoptKey;
247     gXmlSecMSCryptoFunctions->cryptoAppDefaultKeysMngrLoad      = xmlSecMSCryptoAppDefaultKeysMngrLoad;
248     gXmlSecMSCryptoFunctions->cryptoAppDefaultKeysMngrSave      = xmlSecMSCryptoAppDefaultKeysMngrSave;
249 #ifndef XMLSEC_NO_X509
250     gXmlSecMSCryptoFunctions->cryptoAppKeysMngrCertLoad         = xmlSecMSCryptoAppKeysMngrCertLoad;
251     gXmlSecMSCryptoFunctions->cryptoAppKeysMngrCertLoadMemory   = xmlSecMSCryptoAppKeysMngrCertLoadMemory;
252     gXmlSecMSCryptoFunctions->cryptoAppPkcs12Load               = xmlSecMSCryptoAppPkcs12Load;
253     gXmlSecMSCryptoFunctions->cryptoAppPkcs12LoadMemory         = xmlSecMSCryptoAppPkcs12LoadMemory;
254     gXmlSecMSCryptoFunctions->cryptoAppKeyCertLoad              = xmlSecMSCryptoAppKeyCertLoad;
255     gXmlSecMSCryptoFunctions->cryptoAppKeyCertLoadMemory        = xmlSecMSCryptoAppKeyCertLoadMemory;
256 #endif /* XMLSEC_NO_X509 */
257     gXmlSecMSCryptoFunctions->cryptoAppKeyLoad                  = xmlSecMSCryptoAppKeyLoad;
258     gXmlSecMSCryptoFunctions->cryptoAppKeyLoadMemory            = xmlSecMSCryptoAppKeyLoadMemory;
259     gXmlSecMSCryptoFunctions->cryptoAppDefaultPwdCallback       = (void*)xmlSecMSCryptoAppGetDefaultPwdCallback();
260 
261     return(gXmlSecMSCryptoFunctions);
262 }
263 
264 /**
265  * xmlSecMSCryptoInit:
266  *
267  * XMLSec library specific crypto engine initialization.
268  *
269  * Returns: 0 on success or a negative value otherwise.
270  */
271 int
xmlSecMSCryptoInit(void)272 xmlSecMSCryptoInit (void)  {
273     /* Check loaded xmlsec library version */
274     if(xmlSecCheckVersionExact() != 1) {
275         xmlSecInternalError("xmlSecCheckVersionExact", NULL);
276         return(-1);
277     }
278 
279     /* set default errors callback for xmlsec to us */
280     xmlSecErrorsSetCallback(xmlSecMSCryptoErrorsDefaultCallback);
281 
282     /* register our klasses */
283     if(xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms(xmlSecCryptoGetFunctions_mscrypto()) < 0) {
284         xmlSecInternalError("xmlSecCryptoDLFunctionsRegisterKeyDataAndTransforms", NULL);
285         return(-1);
286     }
287     return(0);
288 }
289 
290 /**
291  * xmlSecMSCryptoShutdown:
292  *
293  * XMLSec library specific crypto engine shutdown.
294  *
295  * Returns: 0 on success or a negative value otherwise.
296  */
297 int
xmlSecMSCryptoShutdown(void)298 xmlSecMSCryptoShutdown(void) {
299     /* TODO: if necessary, do additional shutdown here */
300     return(0);
301 }
302 
303 /**
304  * xmlSecMSCryptoKeysMngrInit:
305  * @mngr:               the pointer to keys manager.
306  *
307  * Adds MSCrypto specific key data stores in keys manager.
308  *
309  * Returns: 0 on success or a negative value otherwise.
310  */
311 int
xmlSecMSCryptoKeysMngrInit(xmlSecKeysMngrPtr mngr)312 xmlSecMSCryptoKeysMngrInit(xmlSecKeysMngrPtr mngr) {
313     int ret;
314 
315     xmlSecAssert2(mngr != NULL, -1);
316 
317 #ifndef XMLSEC_NO_X509
318     /* create x509 store if needed */
319     if(xmlSecKeysMngrGetDataStore(mngr, xmlSecMSCryptoX509StoreId) == NULL) {
320         xmlSecKeyDataStorePtr x509Store;
321 
322         x509Store = xmlSecKeyDataStoreCreate(xmlSecMSCryptoX509StoreId);
323         if(x509Store == NULL) {
324             xmlSecInternalError("xmlSecKeyDataStoreCreate(xmlSecMSCryptoX509StoreId)", NULL);
325             return(-1);
326         }
327 
328         ret = xmlSecKeysMngrAdoptDataStore(mngr, x509Store);
329         if(ret < 0) {
330             xmlSecInternalError("xmlSecKeysMngrAdoptDataStore", NULL);
331             xmlSecKeyDataStoreDestroy(x509Store);
332             return(-1);
333         }
334     }
335 #endif /* XMLSEC_NO_X509 */
336 
337     return(0);
338 }
339 
340 static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Random[] = {
341     { MS_STRONG_PROV,               PROV_RSA_FULL },
342     { MS_ENHANCED_PROV,             PROV_RSA_FULL },
343     { NULL, 0 }
344 };
345 
346 /**
347  * xmlSecMSCryptoGenerateRandom:
348  * @buffer:             the destination buffer.
349  * @size:               the numer of bytes to generate.
350  *
351  * Generates @size random bytes and puts result in @buffer
352  * (not implemented yet).
353  *
354  * Returns: 0 on success or a negative value otherwise.
355  */
356 int
xmlSecMSCryptoGenerateRandom(xmlSecBufferPtr buffer,xmlSecSize size)357 xmlSecMSCryptoGenerateRandom(xmlSecBufferPtr buffer, xmlSecSize size) {
358     HCRYPTPROV hProv = 0;
359     int ret;
360 
361     xmlSecAssert2(buffer != NULL, -1);
362     xmlSecAssert2(size > 0, -1);
363 
364     ret = xmlSecBufferSetSize(buffer, size);
365     if(ret < 0) {
366         xmlSecInternalError2("xmlSecBufferSetSize", NULL,
367                              "size=%d", size);
368         return(-1);
369     }
370 
371     hProv = xmlSecMSCryptoFindProvider(xmlSecMSCryptoProviderInfo_Random, NULL, CRYPT_VERIFYCONTEXT, FALSE);
372     if (0 == hProv) {
373         xmlSecInternalError("xmlSecMSCryptoFindProvider", NULL);
374         return(-1);
375     }
376     if (FALSE == CryptGenRandom(hProv, (DWORD)size, xmlSecBufferGetData(buffer))) {
377         xmlSecMSCryptoError("CryptGenRandom", NULL);
378         CryptReleaseContext(hProv,0);
379         return(-1);
380     }
381 
382     CryptReleaseContext(hProv, 0);
383     return(0);
384 }
385 
386 /**
387  * xmlSecMSCryptoGetErrorMessage:
388  * @dwError:            the error code.
389  * @out:                the output buffer.
390  * $outSize:            the output buffer size.
391  *
392  * Returns the system error message for the give error code.
393  */
394 void
xmlSecMSCryptoGetErrorMessage(DWORD dwError,xmlChar * out,xmlSecSize outSize)395 xmlSecMSCryptoGetErrorMessage(DWORD dwError, xmlChar * out, xmlSecSize outSize) {
396     LPTSTR errorText = NULL;
397     DWORD ret;
398 #ifndef UNICODE
399     WCHAR errorTextW[XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE];
400 #endif /* UNICODE */
401 
402     xmlSecAssert(out != NULL);
403     xmlSecAssert(outSize > 0);
404 
405     /* Use system message tables to retrieve error text, allocate buffer on local
406        heap for error text, don't use any inserts/parameters */
407     ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
408                       | FORMAT_MESSAGE_ALLOCATE_BUFFER
409                       | FORMAT_MESSAGE_IGNORE_INSERTS,
410                       NULL,
411                       dwError,
412                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
413                       (LPTSTR)&errorText,
414                       0,
415                       NULL);
416     if((ret <= 0) || (errorText == NULL)) {
417         out[0] = '\0';
418         goto done;
419     }
420 
421 #ifdef UNICODE
422     ret = WideCharToMultiByte(CP_UTF8, 0, errorText, -1, (LPSTR)out, outSize, NULL, NULL);
423     if(ret <= 0) {
424         out[0] = '\0';
425         goto done;
426     }
427 #else /* UNICODE */
428     ret = MultiByteToWideChar(CP_ACP, 0, errorText, -1, errorTextW, XMLSEC_MSCRYPTO_ERROR_MSG_BUFFER_SIZE);
429     if(ret <= 0) {
430         out[0] = '\0';
431         goto done;
432     }
433     ret = WideCharToMultiByte(CP_UTF8, 0, errorTextW, -1, (LPSTR)out, outSize, NULL, NULL);
434     if(ret <= 0) {
435         out[0] = '\0';
436         goto done;
437     }
438 #endif /* UNICODE */
439 
440 done:
441     if(errorText != NULL) {
442         LocalFree(errorText);
443     }
444     return;
445 }
446 
447 
448 /**
449  * xmlSecMSCryptoErrorsDefaultCallback:
450  * @file:               the error location file name (__FILE__ macro).
451  * @line:               the error location line number (__LINE__ macro).
452  * @func:               the error location function name (__FUNCTION__ macro).
453  * @errorObject:        the error specific error object
454  * @errorSubject:       the error specific error subject.
455  * @reason:             the error code.
456  * @msg:                the additional error message.
457  *
458  * The default errors reporting callback function. Just a pass through to the default callback.
459  */
460 void
xmlSecMSCryptoErrorsDefaultCallback(const char * file,int line,const char * func,const char * errorObject,const char * errorSubject,int reason,const char * msg)461 xmlSecMSCryptoErrorsDefaultCallback(const char* file, int line, const char* func,
462                                 const char* errorObject, const char* errorSubject,
463                                 int reason, const char* msg) {
464     xmlSecErrorsDefaultCallback(file, line, func, errorObject, errorSubject, reason, msg);
465 }
466 
467 /**
468  * xmlSecMSCryptoConvertUtf8ToUnicode:
469  * @str:         the string to convert.
470  *
471  * Converts input string from UTF8 to Unicode.
472  *
473  * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs.
474  */
475 LPWSTR
xmlSecMSCryptoConvertUtf8ToUnicode(const xmlChar * str)476 xmlSecMSCryptoConvertUtf8ToUnicode(const xmlChar* str) {
477     return(xmlSecWin32ConvertUtf8ToUnicode(str));
478 }
479 
480 /**
481  * xmlSecMSCryptoConvertUnicodeToUtf8:
482  * @str:         the string to convert.
483  *
484  * Converts input string from Unicode to UTF8.
485  *
486  * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs.
487  */
488 xmlChar*
xmlSecMSCryptoConvertUnicodeToUtf8(LPCWSTR str)489 xmlSecMSCryptoConvertUnicodeToUtf8(LPCWSTR str) {
490     return(xmlSecWin32ConvertUnicodeToUtf8(str));
491 }
492 
493 /**
494  * xmlSecMSCryptoConvertLocaleToUnicode:
495  * @str:         the string to convert.
496  *
497  * Converts input string from current system locale to Unicode.
498  *
499  * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs.
500  */
501 LPWSTR
xmlSecMSCryptoConvertLocaleToUnicode(const char * str)502 xmlSecMSCryptoConvertLocaleToUnicode(const char* str) {
503     return(xmlSecWin32ConvertLocaleToUnicode(str));
504 }
505 
506 /**
507  * xmlSecMSCryptoConvertLocaleToUtf8:
508  * @str:         the string to convert.
509  *
510  * Converts input string from locale to UTF8.
511  *
512  * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs.
513  */
514 xmlChar*
xmlSecMSCryptoConvertLocaleToUtf8(const char * str)515 xmlSecMSCryptoConvertLocaleToUtf8(const char * str) {
516     return(xmlSecWin32ConvertLocaleToUtf8(str));
517 }
518 
519 /**
520  * xmlSecMSCryptoConvertUtf8ToLocale:
521  * @str:         the string to convert.
522  *
523  * Converts input string from UTF8 to locale.
524  *
525  * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs.
526  */
527 char *
xmlSecMSCryptoConvertUtf8ToLocale(const xmlChar * str)528 xmlSecMSCryptoConvertUtf8ToLocale(const xmlChar* str) {
529     return(xmlSecWin32ConvertUtf8ToLocale(str));
530 }
531 
532 /**
533  * xmlSecMSCryptoConvertTstrToUtf8:
534  * @str:         the string to convert.
535  *
536  * Converts input string from TSTR (locale or Unicode) to UTF8.
537  *
538  * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs.
539  */
540 xmlChar*
xmlSecMSCryptoConvertTstrToUtf8(LPCTSTR str)541 xmlSecMSCryptoConvertTstrToUtf8(LPCTSTR str) {
542     return(xmlSecWin32ConvertTstrToUtf8(str));
543 }
544 
545 /**
546  * xmlSecMSCryptoConvertUtf8ToTstr:
547  * @str:         the string to convert.
548  *
549  * Converts input string from UTF8 to TSTR (locale or Unicode).
550  *
551  * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs.
552  */
553 LPTSTR
xmlSecMSCryptoConvertUtf8ToTstr(const xmlChar * str)554 xmlSecMSCryptoConvertUtf8ToTstr(const xmlChar*  str) {
555     return(xmlSecWin32ConvertUtf8ToTstr(str));
556 }
557 
558 /********************************************************************
559  *
560  * Crypto Providers
561  *
562  ********************************************************************/
563 /**
564  * xmlSecMSCryptoFindProvider:
565  * @providers:           the pointer to list of providers, last provider should have NULL for name.
566  * @pszContainer:        the container name for CryptAcquireContext call
567  * @dwFlags:             the flags for CryptAcquireContext call
568  * @bUseXmlSecContainer: the flag to indicate whether we should try to use XmlSec container if default fails
569  *
570  * Finds the first provider from the list
571  *
572  * Returns: provider handle on success or NULL for error.
573  */
574 HCRYPTPROV
xmlSecMSCryptoFindProvider(const xmlSecMSCryptoProviderInfo * providers,LPCTSTR pszContainer,DWORD dwFlags,BOOL bUseXmlSecContainer)575 xmlSecMSCryptoFindProvider(const xmlSecMSCryptoProviderInfo * providers,
576                            LPCTSTR pszContainer,
577                            DWORD dwFlags,
578                            BOOL bUseXmlSecContainer)
579 {
580     HCRYPTPROV res = 0;
581     DWORD dwLastError;
582     BOOL ret;
583     int ii;
584 
585     xmlSecAssert2(providers != NULL, 0);
586 
587     for(ii = 0; (res == 0) && (providers[ii].providerName != NULL) && (providers[ii].providerType != 0); ++ii) {
588         /* first try */
589         ret = CryptAcquireContext(&res,
590                     pszContainer,
591                     providers[ii].providerName,
592                     providers[ii].providerType,
593                     dwFlags);
594         if((ret == TRUE) && (res != 0)) {
595             return (res);
596         }
597 
598         /* check errors */
599         dwLastError = GetLastError();
600         switch(dwLastError) {
601         case NTE_BAD_KEYSET:
602             /* This error can indicate that a newly installed provider
603              * does not have a usable key container yet. It needs to be
604              * created, and then we have to try again CryptAcquireContext.
605              * This is also referenced in
606              * http://www.microsoft.com/mind/0697/crypto.asp (inituser)
607              */
608             ret = CryptAcquireContext(&res,
609                         pszContainer,
610                         providers[ii].providerName,
611                         providers[ii].providerType,
612                         CRYPT_NEWKEYSET | dwFlags);
613             if((ret == TRUE) && (res != 0)) {
614                 return (res);
615             }
616             break;
617 
618         case NTE_EXISTS:
619             /* If we can, try our container */
620             if(bUseXmlSecContainer == TRUE) {
621                 ret = CryptAcquireContext(&res,
622                             XMLSEC_CONTAINER_NAME,
623                             providers[ii].providerName,
624                             providers[ii].providerType,
625                             CRYPT_NEWKEYSET | dwFlags);
626                 if((ret == TRUE) && (res != 0)) {
627                     /* ALEKSEY TODO - NEED TO DELETE ALL THE TEMP CONTEXTS ON SHUTDOWN
628 
629                         CryptAcquireContext(&tmp, XMLSEC_CONTAINER_NAME,
630                             providers[ii].providerName,
631                             providers[ii].providerType,
632                             CRYPT_DELETEKEYSET);
633 
634                      */
635                     return (res);
636                 }
637             }
638             break;
639 
640         default:
641             /* ignore */
642             break;
643         }
644     }
645 
646     return (0);
647 }
648 
649 
650 /********************************************************************
651  *
652  * Utils
653  *
654  ********************************************************************/
655 int
ConvertEndian(const xmlSecByte * src,xmlSecByte * dst,xmlSecSize size)656 ConvertEndian(const xmlSecByte * src, xmlSecByte * dst, xmlSecSize size) {
657     xmlSecByte * p;
658 
659     xmlSecAssert2(src != NULL, -1);
660     xmlSecAssert2(dst != NULL, -1);
661     xmlSecAssert2(size > 0, -1);
662 
663     for(p = dst + size - 1; p >= dst; ++src, --p) {
664         (*p) = (*src);
665     }
666 
667     return (0);
668 }
669 
670 int
ConvertEndianInPlace(xmlSecByte * buf,xmlSecSize size)671 ConvertEndianInPlace(xmlSecByte * buf, xmlSecSize size) {
672     xmlSecByte * p;
673     xmlSecByte ch;
674 
675     xmlSecAssert2(buf != NULL, -1);
676     xmlSecAssert2(size > 0, -1);
677 
678     for(p = buf + size - 1; p >= buf; ++buf, --p) {
679         ch = (*p);
680         (*p) = (*buf);
681         (*buf) = ch;
682     }
683     return (0);
684 }
685 
686 
687