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