Git init
[external/xmlsec1.git] / src / mscrypto / app.c
1 /** 
2  * XMLSec library
3  *
4  * This is free software; see Copyright file in the source
5  * distribution for preciese wording.
6  * 
7  * Copyrigth (C) 2003 Cordys R&D BV, All rights reserved.
8  * Copyright (C) 2003 Aleksey Sanin <aleksey@aleksey.com>
9  */
10 #include "globals.h"
11
12 #include <string.h>
13
14 #include <windows.h>
15 #include <wincrypt.h>
16
17 #include <xmlsec/xmlsec.h>
18 #include <xmlsec/keys.h>
19 #include <xmlsec/transforms.h>
20 #include <xmlsec/errors.h>
21
22 #include <xmlsec/mscrypto/app.h>
23 #include <xmlsec/mscrypto/crypto.h>
24 #include <xmlsec/mscrypto/certkeys.h>
25 #include <xmlsec/mscrypto/keysstore.h>
26 #include <xmlsec/mscrypto/x509.h>
27
28 #if defined(__MINGW32__)
29 #  include "xmlsec-mingw.h"
30 #endif
31
32 /* I don't see any other way then to use a global var to get the 
33  * config info to the mscrypto keysstore :(  WK 
34  */
35 static char *gXmlSecMSCryptoAppCertStoreName = NULL;
36
37 /**
38  * xmlSecMSCryptoAppInit:
39  * @config:             the name of another then the default ms certificate store.
40  * 
41  * General crypto engine initialization. This function is used
42  * by XMLSec command line utility and called before 
43  * @xmlSecInit function.
44  *
45  * Returns: 0 on success or a negative value otherwise.
46  */
47 int
48 xmlSecMSCryptoAppInit(const char* config) {
49     /* initialize MSCrypto crypto engine */
50
51     /* config parameter can contain *another* ms certs store name 
52      * then the default (MY)
53      */
54     if (NULL != config && strlen(config) > 0) {
55         if (gXmlSecMSCryptoAppCertStoreName) {
56             /* This should not happen, initialize twice */
57             xmlSecError(XMLSEC_ERRORS_HERE,
58                         NULL,
59                         NULL,
60                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
61                         "config=%s, config already set", 
62                         xmlSecErrorsSafeString(config));
63             return (-1);
64         }
65         gXmlSecMSCryptoAppCertStoreName = xmlStrdup(config);
66     }
67
68     return(0);
69 }
70
71 /**
72  * xmlSecMSCryptoAppShutdown:
73  * 
74  * General crypto engine shutdown. This function is used
75  * by XMLSec command line utility and called after 
76  * @xmlSecShutdown function.
77  *
78  * Returns: 0 on success or a negative value otherwise.
79  */
80 int
81 xmlSecMSCryptoAppShutdown(void) {
82     /* shutdown MSCrypto crypto engine */
83     if (NULL != gXmlSecMSCryptoAppCertStoreName) {
84         xmlFree(gXmlSecMSCryptoAppCertStoreName);
85         gXmlSecMSCryptoAppCertStoreName = NULL;
86     }
87     return(0);
88 }
89
90 /**
91  * xmlSecMSCryptoAppGetCertStoreName:
92  *
93  * Gets the MS Crypto certs store name set by @xmlSecMSCryptoAppInit function.
94  *
95  * Returns: the MS Crypto certs name used by xmlsec-mscrypto.
96  */
97 const char*
98 xmlSecMSCryptoAppGetCertStoreName(void) {
99     return(gXmlSecMSCryptoAppCertStoreName);
100 }
101
102 /*************************************************************************************
103  * Keys 
104  *************************************************************************************/
105
106 /**
107  * xmlSecMSCryptoAppKeyLoad:
108  * @filename:           the key filename.
109  * @format:             the key file format.
110  * @pwd:                the key file password.
111  * @pwdCallback:        the key password callback.
112  * @pwdCallbackCtx:     the user context for password callback.
113  *
114  * Reads key from the a file.
115  *
116  * Returns: pointer to the key or NULL if an error occurs.
117  */
118 xmlSecKeyPtr
119 xmlSecMSCryptoAppKeyLoad(const char *filename, xmlSecKeyDataFormat format,
120                          const char *pwd, void* pwdCallback, void* pwdCallbackCtx) {
121     xmlSecBuffer buffer;
122     xmlSecKeyPtr key = NULL;
123     int ret;    
124     
125     xmlSecAssert2(filename != NULL, NULL);
126     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);
127     
128     switch (format) {
129     case xmlSecKeyDataFormatPkcs12:
130         key = xmlSecMSCryptoAppPkcs12Load(filename, pwd, pwdCallback, pwdCallbackCtx);
131         if(key == NULL) {
132             xmlSecError(XMLSEC_ERRORS_HERE,
133                         NULL,
134                         "xmlSecMSCryptoAppPkcs12Load",
135                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
136                         XMLSEC_ERRORS_NO_MESSAGE);
137             return(NULL);       
138         }
139         break;
140     case xmlSecKeyDataFormatCertDer:
141         ret = xmlSecBufferInitialize(&buffer, 0);
142         if(ret < 0) {
143             xmlSecError(XMLSEC_ERRORS_HERE,
144                         NULL,
145                         "xmlSecBufferInitialize",
146                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
147                         XMLSEC_ERRORS_NO_MESSAGE);
148             return(NULL);       
149         }
150
151         ret = xmlSecBufferReadFile(&buffer, filename);
152         if(ret < 0) {
153             xmlSecError(XMLSEC_ERRORS_HERE,
154                         NULL,
155                         "xmlSecBufferReadFile",
156                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
157                         "filename=%s", 
158                         xmlSecErrorsSafeString(filename));
159             xmlSecBufferFinalize(&buffer);
160             return (NULL);
161         }
162         
163         key = xmlSecMSCryptoAppKeyLoadMemory(xmlSecBufferGetData(&buffer),
164                                         xmlSecBufferGetSize(&buffer), format,
165                                         pwd, pwdCallback, pwdCallbackCtx);
166         if(key == NULL) {
167             xmlSecError(XMLSEC_ERRORS_HERE,
168                         NULL,
169                         "xmlSecMSCryptoAppKeyLoadMemory",
170                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
171                         XMLSEC_ERRORS_NO_MESSAGE);
172             xmlSecBufferFinalize(&buffer);
173             return(NULL);       
174         }
175         xmlSecBufferFinalize(&buffer);
176         break;
177     default:
178         /* Any other format like PEM keys is currently not supported */
179         xmlSecError(XMLSEC_ERRORS_HERE,
180                     NULL,
181                     NULL,
182                     XMLSEC_ERRORS_R_INVALID_FORMAT,
183                     "format=%d", format);
184         return(NULL);
185     }
186
187     return(key);
188 }
189
190 /**
191  * xmlSecMSCryptoAppKeyLoadMemory:
192  * @data:               the key binary data.
193  * @dataSize:           the key data size.
194  * @format:             the key format.
195  * @pwd:                the key password.
196  * @pwdCallback:        the key password callback.
197  * @pwdCallbackCtx:     the user context for password callback.
198  *
199  * Reads key from the a file.
200  *
201  * Returns: pointer to the key or NULL if an error occurs.
202  */
203 xmlSecKeyPtr    
204 xmlSecMSCryptoAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize, xmlSecKeyDataFormat format,
205                                const char *pwd, void* pwdCallback, void* pwdCallbackCtx) {
206     PCCERT_CONTEXT pCert = NULL;
207     PCCERT_CONTEXT tmpcert = NULL;
208     xmlSecKeyDataPtr x509Data = NULL;
209     xmlSecKeyDataPtr keyData = NULL;
210     xmlSecKeyPtr key = NULL;
211     xmlSecKeyPtr res = NULL;
212     int ret;
213
214     xmlSecAssert2(data != NULL, NULL);
215     xmlSecAssert2(dataSize > 0, NULL);
216     xmlSecAssert2(format == xmlSecKeyDataFormatCertDer, NULL);
217
218     pCert = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, data, dataSize);
219     if (NULL == pCert) {
220         xmlSecError(XMLSEC_ERRORS_HERE,
221                     NULL,
222                     "CertCreateCertificateContext",
223                     XMLSEC_ERRORS_R_IO_FAILED,
224                     XMLSEC_ERRORS_NO_MESSAGE);
225         goto done;
226     }
227
228     x509Data = xmlSecKeyDataCreate(xmlSecMSCryptoKeyDataX509Id);
229     if(x509Data == NULL) {
230         xmlSecError(XMLSEC_ERRORS_HERE,
231                     NULL,
232                     "xmlSecKeyDataCreate",
233                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
234                     "transform=%s",
235                     xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecMSCryptoKeyDataX509Id)));
236         goto done;
237     }
238
239     tmpcert = CertDuplicateCertificateContext(pCert);
240     if(tmpcert == NULL) {
241         xmlSecError(XMLSEC_ERRORS_HERE,
242                     NULL,
243                     "CertDuplicateCertificateContext",
244                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
245                     "data=%s",
246                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
247         goto done;
248     }
249
250     ret = xmlSecMSCryptoKeyDataX509AdoptKeyCert(x509Data, tmpcert);
251     if(ret < 0) {
252         xmlSecError(XMLSEC_ERRORS_HERE,
253                     NULL,
254                     "xmlSecMSCryptoKeyDataX509AdoptKeyCert",
255                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
256                     "data=%s",
257                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
258         CertFreeCertificateContext(tmpcert);
259         goto done;
260     }
261     tmpcert = NULL;
262
263     keyData = xmlSecMSCryptoCertAdopt(pCert, xmlSecKeyDataTypePublic);
264     if(keyData == NULL) {
265         xmlSecError(XMLSEC_ERRORS_HERE,
266                     NULL,
267                     "xmlSecMSCryptoCertAdopt",
268                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
269                     XMLSEC_ERRORS_NO_MESSAGE);
270         goto done;
271     }
272     pCert = NULL;    
273
274     key = xmlSecKeyCreate();
275     if(key == NULL) {
276         xmlSecError(XMLSEC_ERRORS_HERE,
277                     NULL,
278                     "xmlSecKeyCreate",
279                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
280                 XMLSEC_ERRORS_NO_MESSAGE);
281         goto done;
282     }    
283     
284     ret = xmlSecKeySetValue(key, keyData);
285     if(ret < 0) {
286         xmlSecError(XMLSEC_ERRORS_HERE,
287                     NULL,
288                     "xmlSecKeySetValue",
289                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
290                     "data=%s",
291                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
292         goto done;
293     }
294     keyData = NULL;
295
296     ret = xmlSecKeyAdoptData(key, x509Data);
297     if(ret < 0) {
298         xmlSecError(XMLSEC_ERRORS_HERE,
299                     NULL,
300                     "xmlSecKeyAdoptData",
301                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
302                     "data=%s",
303                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
304         goto done;
305     }
306     x509Data = NULL;
307
308     /* success */
309     res = key;
310     key = NULL;
311 done:
312     if(pCert != NULL) {
313         CertFreeCertificateContext(pCert);
314     }
315     if(tmpcert != NULL) {
316         CertFreeCertificateContext(tmpcert);
317     }
318     if(x509Data != NULL) {
319         xmlSecKeyDataDestroy(x509Data);
320     }
321     if(keyData != NULL) {
322         xmlSecKeyDataDestroy(keyData);
323     }
324     if(key != NULL) {
325         xmlSecKeyDestroy(key);
326     }
327     return(res); 
328 }
329
330
331 /**********************************************************************************
332  * X509 certificates
333  **********************************************************************************/
334
335 #ifndef XMLSEC_NO_X509
336
337 /**
338  * xmlSecMSCryptoAppKeyCertLoad:
339  * @key:                the pointer to key.
340  * @filename:           the certificate filename.
341  * @format:             the certificate file format.
342  *
343  * Reads the certificate from $@filename and adds it to key.
344  * 
345  * Returns: 0 on success or a negative value otherwise.
346  */
347
348 int             
349 xmlSecMSCryptoAppKeyCertLoad(xmlSecKeyPtr key, const char* filename, 
350                              xmlSecKeyDataFormat format) {
351     xmlSecBuffer buffer;
352     int ret;
353
354     xmlSecAssert2(key != NULL, -1);
355     xmlSecAssert2(filename != NULL, -1);
356     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
357                                                                         
358     ret = xmlSecBufferInitialize(&buffer, 0);
359     if(ret < 0) {
360         xmlSecError(XMLSEC_ERRORS_HERE,
361                     NULL,
362                     "xmlSecBufferInitialize",
363                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
364                     XMLSEC_ERRORS_NO_MESSAGE);
365         return(-1);     
366     }
367
368     ret = xmlSecBufferReadFile(&buffer, filename);
369     if(ret < 0) {
370         xmlSecError(XMLSEC_ERRORS_HERE,
371                     NULL,
372                     "xmlSecBufferReadFile",
373                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
374                     "filename=%s", 
375                     xmlSecErrorsSafeString(filename));
376         xmlSecBufferFinalize(&buffer);
377         return (-1);
378     }
379     
380     ret = xmlSecMSCryptoAppKeyCertLoadMemory(key, xmlSecBufferGetData(&buffer), 
381                     xmlSecBufferGetSize(&buffer), format);
382     if (ret < 0) {
383         xmlSecError(XMLSEC_ERRORS_HERE,
384                     NULL,
385                     "xmlSecMSCryptoAppKeyCertLoadMemory",                   
386                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
387                     XMLSEC_ERRORS_NO_MESSAGE);
388         xmlSecBufferFinalize(&buffer);
389         return(-1);
390     }
391     
392     xmlSecBufferFinalize(&buffer);
393     return(0);        
394 }
395
396 /**
397  * xmlSecMSCryptoAppKeyCertLoadMemory:
398  * @key:                the pointer to key.
399  * @data:               the binary certificate.
400  * @dataSize:           size of certificate binary (data)
401  * @format:             the certificate file format.
402  *
403  * Reads the certificate from $@data and adds it to key.
404  * 
405  * Returns: 0 on success or a negative value otherwise.
406  */
407 int             
408 xmlSecMSCryptoAppKeyCertLoadMemory(xmlSecKeyPtr key, const xmlSecByte* data, xmlSecSize dataSize, 
409                                    xmlSecKeyDataFormat format) {
410     PCCERT_CONTEXT pCert;
411     xmlSecKeyDataPtr kdata;
412     int ret;
413         
414     xmlSecAssert2(key != NULL, -1);
415     xmlSecAssert2(data != NULL, -1);
416     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
417
418     kdata = xmlSecKeyEnsureData(key, xmlSecMSCryptoKeyDataX509Id);
419     if(kdata == NULL) {
420         xmlSecError(XMLSEC_ERRORS_HERE,
421                     NULL,
422                     "xmlSecKeyEnsureData",                  
423                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
424                     "transform=%s",
425                     xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecMSCryptoKeyDataX509Id)));
426         return(-1);
427     }
428
429     /* For now only DER certificates are supported */
430     /* adjust cert format */
431     switch(format) {
432     case xmlSecKeyDataFormatDer:
433     case xmlSecKeyDataFormatCertDer:
434         pCert = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, data, dataSize);
435         if (NULL == pCert) {
436             xmlSecError(XMLSEC_ERRORS_HERE,
437                         NULL,
438                         "CertCreateCertificateContext", 
439                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
440                         "format=%d", format);
441             return(-1);    
442         }       
443
444         ret = xmlSecMSCryptoKeyDataX509AdoptCert(kdata, pCert);
445         if(ret < 0) {
446             xmlSecError(XMLSEC_ERRORS_HERE,
447                         NULL,
448                         "xmlSecMSCryptoKeyDataX509AdoptCert",
449                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
450                         "data=%s",
451                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(kdata)));
452             CertFreeCertificateContext(pCert);
453             return(-1);    
454         }
455         break;
456     default:
457         xmlSecError(XMLSEC_ERRORS_HERE,
458                     NULL,
459                     NULL,
460                     XMLSEC_ERRORS_R_INVALID_FORMAT,
461                     "format=%d", (int)format);
462         return(-1);
463     }
464     
465     return(0);        
466 }
467
468 /**
469  * xmlSecMSCryptoAppPkcs12Load:
470  * @filename:           the PKCS12 key filename.
471  * @pwd:                the PKCS12 file password.
472  * @pwdCallback:        the password callback.
473  * @pwdCallbackCtx:     the user context for password callback.
474  *
475  * Reads key and all associated certificates from the PKCS12 file
476  *
477  * Returns: pointer to the key or NULL if an error occurs.
478  */
479 xmlSecKeyPtr    
480 xmlSecMSCryptoAppPkcs12Load(const char *filename, 
481                             const char *pwd,
482                             void* pwdCallback ATTRIBUTE_UNUSED, 
483                             void* pwdCallbackCtx ATTRIBUTE_UNUSED) {
484     xmlSecBuffer buffer;
485     xmlSecKeyPtr key;
486     int ret;
487
488     xmlSecAssert2(filename != NULL, NULL);
489     xmlSecAssert2(pwd != NULL, NULL);
490
491     ret = xmlSecBufferInitialize(&buffer, 0);
492     if(ret < 0) {
493         xmlSecError(XMLSEC_ERRORS_HERE,
494                     NULL,
495                     "xmlSecBufferInitialize",
496                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
497                     XMLSEC_ERRORS_NO_MESSAGE);
498         return(NULL);   
499     }
500
501     ret = xmlSecBufferReadFile(&buffer, filename);
502     if(ret < 0) {
503         xmlSecError(XMLSEC_ERRORS_HERE,
504                     NULL,
505                     "xmlSecBufferReadFile",
506                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
507                     "filename=%s", 
508                     xmlSecErrorsSafeString(filename));
509         xmlSecBufferFinalize(&buffer);
510         return (NULL);
511     }
512     if(xmlSecBufferGetData(&buffer) == NULL) {
513         xmlSecError(XMLSEC_ERRORS_HERE,
514                     NULL,
515                     NULL,
516                     XMLSEC_ERRORS_R_INVALID_DATA,
517                     XMLSEC_ERRORS_NO_MESSAGE);
518         xmlSecBufferFinalize(&buffer);
519         return(NULL);
520     }
521
522     key = xmlSecMSCryptoAppPkcs12LoadMemory(xmlSecBufferGetData(&buffer), 
523                                             xmlSecBufferGetSize(&buffer), pwd,
524                                             pwdCallback, pwdCallbackCtx);
525     if (key == NULL) {
526         xmlSecError(XMLSEC_ERRORS_HERE,
527                     NULL,
528                     "xmlSecMSCryptoAppPkcs12LoadMemory",                    
529                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
530                     XMLSEC_ERRORS_NO_MESSAGE);
531         xmlSecBufferFinalize(&buffer);
532         return(NULL);
533     }
534     
535     xmlSecBufferFinalize(&buffer);
536     return(key);        
537 }
538
539 /**
540  * xmlSecMSCryptoAppPkcs12LoadMemory:
541  * @data:               the binary PKCS12 key in data.
542  * @dataSize:           size of binary pkcs12 data
543  * @pwd:                the PKCS12 file password.
544  * @pwdCallback:        the password callback.
545  * @pwdCallbackCtx:     the user context for password callback.
546  *
547  * Reads key and all associated certificates from the PKCS12 binary
548  *
549  * Returns: pointer to the key or NULL if an error occurs.
550  */
551 xmlSecKeyPtr    
552 xmlSecMSCryptoAppPkcs12LoadMemory(const xmlSecByte* data,
553                                   xmlSecSize dataSize, 
554                                   const char *pwd,
555                                   void* pwdCallback ATTRIBUTE_UNUSED, 
556                                   void* pwdCallbackCtx ATTRIBUTE_UNUSED) {
557     int ret, len;
558     CRYPT_DATA_BLOB pfx;
559     HCERTSTORE hCertStore = NULL;
560     PCCERT_CONTEXT tmpcert = NULL;
561     PCCERT_CONTEXT pCert = NULL;
562     WCHAR* wcPwd = NULL;
563     xmlSecKeyDataPtr x509Data = NULL;
564     xmlSecKeyDataPtr keyData = NULL;
565     xmlSecKeyPtr key = NULL;
566
567     xmlSecAssert2(data != NULL, NULL);
568     xmlSecAssert2(dataSize > 1, NULL);
569     xmlSecAssert2(pwd != NULL, NULL);
570
571     memset(&pfx, 0, sizeof(pfx));
572     pfx.pbData = (BYTE *)data;
573     pfx.cbData = dataSize;
574
575     if(FALSE == PFXIsPFXBlob(&pfx)) {
576         xmlSecError(XMLSEC_ERRORS_HERE,
577                     NULL,
578                     "PFXIsPFXBlob",
579                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
580                     "size=%ld",
581                     pfx.cbData);
582         goto done;
583     }
584
585     len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pwd, -1, NULL, 0);
586     if(len <= 0) {
587         xmlSecError(XMLSEC_ERRORS_HERE,
588                     NULL,
589                     "MultiByteToWideChar",
590                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
591                     XMLSEC_ERRORS_NO_MESSAGE);
592         goto done;
593     }
594
595     wcPwd = (WCHAR *)xmlMalloc((len + 1) * sizeof(WCHAR));
596     if(wcPwd == NULL) {
597         xmlSecError(XMLSEC_ERRORS_HERE,
598                     NULL,
599                     NULL,
600                     XMLSEC_ERRORS_R_MALLOC_FAILED,
601                     "len=%d", len);
602         goto done;
603     }
604
605     ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pwd, -1, wcPwd, len);
606     if (ret <= 0) {
607         xmlSecError(XMLSEC_ERRORS_HERE,
608                     NULL,
609                     "MultiByteToWideChar",
610                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
611                     XMLSEC_ERRORS_NO_MESSAGE);
612         goto done;
613     }
614
615     if (FALSE == PFXVerifyPassword(&pfx, wcPwd, 0)) {
616         xmlSecError(XMLSEC_ERRORS_HERE,
617                     NULL,
618                     "PFXVerifyPassword",
619                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
620                     XMLSEC_ERRORS_NO_MESSAGE);
621         goto done;
622     }
623
624     hCertStore = PFXImportCertStore(&pfx, wcPwd, CRYPT_EXPORTABLE);
625     if (NULL == hCertStore) {
626         xmlSecError(XMLSEC_ERRORS_HERE,
627                     NULL,
628                     "PFXImportCertStore",
629                     XMLSEC_ERRORS_R_CRYPTO_FAILED,
630                     XMLSEC_ERRORS_NO_MESSAGE);
631         goto done;
632     }
633     
634     x509Data = xmlSecKeyDataCreate(xmlSecMSCryptoKeyDataX509Id);
635     if(x509Data == NULL) {
636         xmlSecError(XMLSEC_ERRORS_HERE,
637                     NULL,
638                     "xmlSecKeyDataCreate",
639                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
640                     "transform=%s",
641                     xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecMSCryptoKeyDataX509Id)));
642         goto done;
643     }
644
645     while (pCert = CertEnumCertificatesInStore(hCertStore, pCert)) {
646         DWORD dwData = 0;
647         DWORD dwDataLen = sizeof(DWORD);
648
649         /* Find the certificate that has the private key */
650         if((TRUE == CertGetCertificateContextProperty(pCert, CERT_KEY_SPEC_PROP_ID, &dwData, &dwDataLen)) && (dwData > 0)) {
651             tmpcert = CertDuplicateCertificateContext(pCert);
652             if(tmpcert == NULL) {
653                 xmlSecError(XMLSEC_ERRORS_HERE,
654                             NULL,
655                             "CertDuplicateCertificateContext",
656                             XMLSEC_ERRORS_R_CRYPTO_FAILED,
657                             "data=%s",
658                             xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
659                 goto done;
660             }
661
662             keyData = xmlSecMSCryptoCertAdopt(tmpcert, xmlSecKeyDataTypePrivate | xmlSecKeyDataTypePublic);
663             if(keyData == NULL) {
664                 xmlSecError(XMLSEC_ERRORS_HERE,
665                             NULL,
666                             "xmlSecMSCryptoCertAdopt",
667                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
668                             XMLSEC_ERRORS_NO_MESSAGE);
669                 goto done;
670             }
671         tmpcert = NULL;
672         
673             tmpcert = CertDuplicateCertificateContext(pCert);
674             if(tmpcert == NULL) {
675                 xmlSecError(XMLSEC_ERRORS_HERE,
676                             NULL,
677                             "CertDuplicateCertificateContext",
678                             XMLSEC_ERRORS_R_CRYPTO_FAILED,
679                             "data=%s",
680                             xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
681                 goto done;
682             }
683
684             ret = xmlSecMSCryptoKeyDataX509AdoptKeyCert(x509Data, tmpcert);
685             if(ret < 0) {
686                 xmlSecError(XMLSEC_ERRORS_HERE,
687                     NULL,
688                     "xmlSecMSCryptoKeyDataX509AdoptKeyCert",
689                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
690                     "data=%s",
691                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
692                 goto done;
693             }
694             tmpcert = NULL;
695         }
696
697         /* load certificate in the x509 key data */
698         tmpcert = CertDuplicateCertificateContext(pCert);
699         if(tmpcert == NULL) {
700             xmlSecError(XMLSEC_ERRORS_HERE,
701                         NULL,
702                         "CertDuplicateCertificateContext",
703                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
704                         "data=%s",
705                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
706             goto done;  
707         }
708
709         ret = xmlSecMSCryptoKeyDataX509AdoptCert(x509Data, tmpcert);
710         if(ret < 0) {
711             xmlSecError(XMLSEC_ERRORS_HERE,
712                         NULL,
713                         "xmlSecMSCryptoKeyDataX509AdoptCert",
714                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
715                         "data=%s",
716                         xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
717             goto done;
718         }
719         tmpcert = NULL;
720     }
721
722     if (keyData == NULL) {
723         xmlSecError(XMLSEC_ERRORS_HERE,
724                     NULL,
725                     "xmlSecMSCryptoAppPkcs12Load",
726                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
727                     "private key not found in PKCS12 file");
728         goto done;
729     }
730
731     key = xmlSecKeyCreate();
732     if(key == NULL) {
733         xmlSecError(XMLSEC_ERRORS_HERE,
734                     NULL,
735                     "xmlSecKeyCreate",
736                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
737                     XMLSEC_ERRORS_NO_MESSAGE);
738         goto done;
739     }    
740     
741     ret = xmlSecKeySetValue(key, keyData);
742     if(ret < 0) {
743         xmlSecError(XMLSEC_ERRORS_HERE,
744                     NULL,
745                     "xmlSecKeySetValue",
746                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
747                     "data=%s",
748                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
749         xmlSecKeyDestroy(key);
750         key = NULL;
751         goto done;
752     }
753     keyData = NULL;
754
755     ret = xmlSecKeyAdoptData(key, x509Data);
756     if(ret < 0) {
757         xmlSecError(XMLSEC_ERRORS_HERE,
758                     NULL,
759                     "xmlSecKeyAdoptData",
760                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
761                     "data=%s",
762                     xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
763         xmlSecKeyDestroy(key);
764         key = NULL;
765         goto done;
766     }
767     x509Data = NULL;
768
769 done:
770     if(hCertStore != NULL) {
771         CertCloseStore(hCertStore, 0);
772     }
773     if(wcPwd != NULL) {
774         xmlFree(wcPwd);
775     }
776     if(x509Data != NULL) {
777         xmlSecKeyDataDestroy(x509Data);
778     }
779     if(keyData != NULL) {
780         xmlSecKeyDataDestroy(keyData);
781     }
782     if(tmpcert != NULL) {
783         CertFreeCertificateContext(tmpcert);
784     }
785     return(key); 
786 }
787
788 /**
789  * xmlSecMSCryptoAppKeysMngrCertLoad:
790  * @mngr:               the keys manager.
791  * @filename:           the certificate file.
792  * @format:             the certificate file format.
793  * @type:               the flag that indicates is the certificate in @filename
794  *                      trusted or not.
795  * 
796  * Reads cert from @filename and adds to the list of trusted or known
797  * untrusted certs in @store (not implemented yet).
798  *
799  * Returns: 0 on success or a negative value otherwise.
800  */
801 int
802 xmlSecMSCryptoAppKeysMngrCertLoad(xmlSecKeysMngrPtr mngr, const char *filename, 
803                                 xmlSecKeyDataFormat format, 
804                                 xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
805     xmlSecBuffer buffer;
806     int ret;
807     
808     xmlSecAssert2(mngr != NULL, -1);
809     xmlSecAssert2(filename != NULL, -1);
810     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
811
812     ret = xmlSecBufferInitialize(&buffer, 0);
813     if(ret < 0) {
814         xmlSecError(XMLSEC_ERRORS_HERE,
815                     NULL,
816                     "xmlSecBufferInitialize",
817                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
818                     XMLSEC_ERRORS_NO_MESSAGE);
819         return(-1);     
820     }
821
822     ret = xmlSecBufferReadFile(&buffer, filename);
823     if(ret < 0) {
824         xmlSecError(XMLSEC_ERRORS_HERE,
825                     NULL,
826                     "xmlSecBufferReadFile",
827                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
828                     "filename=%s", 
829                     xmlSecErrorsSafeString(filename));
830         xmlSecBufferFinalize(&buffer);
831         return (-1);
832     }
833
834     ret = xmlSecMSCryptoAppKeysMngrCertLoadMemory(mngr, xmlSecBufferGetData(&buffer),
835         xmlSecBufferGetSize(&buffer), format, type);
836     if (ret < 0) {
837         xmlSecError(XMLSEC_ERRORS_HERE,
838                     NULL,
839                     "xmlSecMSCryptoAppKeysMngrCertLoadMemory",
840                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
841                     "filename=%s", 
842                     xmlSecErrorsSafeString(filename));
843         xmlSecBufferFinalize(&buffer);
844         return(-1);
845     }
846     
847     xmlSecBufferFinalize(&buffer);
848     return(ret);                         
849 }
850
851 /**
852  * xmlSecMSCryptoAppKeysMngrCertLoadMemory:
853  * @mngr:               the keys manager.
854  * @data:               the binary certificate.
855  * @dataSize:           size of binary certificate (data)
856  * @format:             the certificate file format.
857  * @type:               the flag that indicates is the certificate in @filename
858  *                      trusted or not.
859  *
860  * Reads cert from @data and adds to the list of trusted or known
861  * untrusted certs in @store.
862  *
863  * Returns: 0 on success or a negative value otherwise.
864  */
865 int
866 xmlSecMSCryptoAppKeysMngrCertLoadMemory(xmlSecKeysMngrPtr mngr, const xmlSecByte* data,
867                                         xmlSecSize dataSize, xmlSecKeyDataFormat format, 
868                                         xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
869     xmlSecKeyDataStorePtr x509Store;
870     PCCERT_CONTEXT pCert = NULL;
871     int ret;
872
873     xmlSecAssert2(mngr != NULL, -1);
874     xmlSecAssert2(data != NULL, -1);
875     xmlSecAssert2(dataSize > 0, -1);
876     xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
877
878     x509Store = xmlSecKeysMngrGetDataStore(mngr, xmlSecMSCryptoX509StoreId);
879     if(x509Store == NULL) {
880         xmlSecError(XMLSEC_ERRORS_HERE,
881                     NULL,
882                     "xmlSecKeysMngrGetDataStore",
883                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
884                     "xmlSecMSCryptoX509StoreId");
885         return(-1);
886     }
887
888     switch (format) {
889         case xmlSecKeyDataFormatDer:
890         case xmlSecKeyDataFormatCertDer:
891             pCert = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
892                                                  data, dataSize);
893             if (NULL == pCert) {
894                 xmlSecError(XMLSEC_ERRORS_HERE,
895                             NULL,
896                             "CertCreateCertificateContext",
897                             XMLSEC_ERRORS_R_CRYPTO_FAILED,
898                             XMLSEC_ERRORS_NO_MESSAGE);
899                 return (-1);
900             }
901             break;
902         default:
903             xmlSecError(XMLSEC_ERRORS_HERE,
904                         NULL,
905                         NULL,
906                         XMLSEC_ERRORS_R_INVALID_FORMAT,
907                         "format=%d", format); 
908             return(-1);
909     }
910
911     xmlSecAssert2(pCert != NULL, -1);
912     ret = xmlSecMSCryptoX509StoreAdoptCert(x509Store, pCert, type);
913     if(ret < 0) {
914         xmlSecError(XMLSEC_ERRORS_HERE,
915                     NULL,
916                     "xmlSecMSCryptoX509StoreAdoptCert",
917                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
918                     XMLSEC_ERRORS_NO_MESSAGE);
919         CertFreeCertificateContext(pCert);
920         return(-1);
921     }
922
923     return(0);
924 }
925
926 /** 
927  * xmlSecMSCryptoAppDefaultKeysMngrAdoptKeyStore: 
928  * @mngr:                       the keys manager.
929  * @keyStore:           the pointer to keys store.
930  *
931  * Adds @keyStore to the list of key stores in the keys manager @mngr.
932  *
933  * Returns: 0 on success or a negative value if an error occurs.
934  */
935 int 
936 xmlSecMSCryptoAppDefaultKeysMngrAdoptKeyStore(xmlSecKeysMngrPtr mngr, HCERTSTORE keyStore)
937 {
938         xmlSecKeyDataStorePtr x509Store ;
939
940         xmlSecAssert2( mngr != NULL, -1 ) ;
941         xmlSecAssert2( keyStore != NULL, -1 ) ;
942
943     x509Store = xmlSecKeysMngrGetDataStore( mngr, xmlSecMSCryptoX509StoreId) ;
944         if( x509Store == NULL ) {
945                 xmlSecError( XMLSEC_ERRORS_HERE ,
946                         NULL ,
947                         "xmlSecKeysMngrGetDataStore" ,
948                         XMLSEC_ERRORS_R_XMLSEC_FAILED ,
949                         XMLSEC_ERRORS_NO_MESSAGE ) ;
950                 return(-1) ;
951         }
952
953         if( xmlSecMSCryptoX509StoreAdoptKeyStore( x509Store, keyStore ) < 0 ) {
954                 xmlSecError( XMLSEC_ERRORS_HERE ,
955                         xmlSecErrorsSafeString( xmlSecKeyDataStoreGetName( x509Store ) ) ,
956                         "xmlSecMSCryptoX509StoreAdoptKeyStore" ,
957                         XMLSEC_ERRORS_R_XMLSEC_FAILED ,
958                         XMLSEC_ERRORS_NO_MESSAGE ) ;
959                 return(-1) ;
960         }
961
962         return (0) ;
963 }
964
965 /** 
966  * xmlSecMSCryptoAppDefaultKeysMngrAdoptTrustedStore: 
967  * @mngr:                       the keys manager.
968  * @trustedStore:       the pointer to certs store.
969  *
970  * Adds @trustedStore to the list of trusted cert stores in the keys manager @mngr.
971  *
972  * Returns: 0 on success or a negative value if an error occurs.
973  */
974 int
975 xmlSecMSCryptoAppDefaultKeysMngrAdoptTrustedStore(xmlSecKeysMngrPtr mngr, HCERTSTORE trustedStore)
976 {
977         xmlSecKeyDataStorePtr x509Store ;
978
979         xmlSecAssert2( mngr != NULL, -1 ) ;
980         xmlSecAssert2( trustedStore != NULL, -1 ) ;
981
982     x509Store = xmlSecKeysMngrGetDataStore( mngr, xmlSecMSCryptoX509StoreId ) ;
983         if( x509Store == NULL ) {
984                 xmlSecError( XMLSEC_ERRORS_HERE ,
985                         NULL ,
986                         "xmlSecKeysMngrGetDataStore" ,
987                         XMLSEC_ERRORS_R_XMLSEC_FAILED ,
988                         XMLSEC_ERRORS_NO_MESSAGE ) ;
989                 return(-1) ;
990         }
991
992         if( xmlSecMSCryptoX509StoreAdoptTrustedStore( x509Store, trustedStore ) < 0 ) {
993                 xmlSecError( XMLSEC_ERRORS_HERE ,
994                         xmlSecErrorsSafeString( xmlSecKeyDataStoreGetName( x509Store ) ) ,
995                         "xmlSecMSCryptoX509StoreAdoptKeyStore" ,
996                         XMLSEC_ERRORS_R_XMLSEC_FAILED ,
997                         XMLSEC_ERRORS_NO_MESSAGE ) ;
998                 return(-1) ;
999         }
1000
1001         return(0);
1002 }
1003
1004 /** 
1005  * xmlSecMSCryptoAppDefaultKeysMngrAdoptUntrustedStore: 
1006  * @mngr:                       the keys manager.
1007  * @untrustedStore:     the pointer to certs store.
1008  *
1009  * Adds @trustedStore to the list of un-trusted cert stores in the keys manager @mngr.
1010  *
1011  * Returns: 0 on success or a negative value if an error occurs.
1012  */
1013 int
1014 xmlSecMSCryptoAppDefaultKeysMngrAdoptUntrustedStore(xmlSecKeysMngrPtr mngr, HCERTSTORE untrustedStore)
1015 {
1016         xmlSecKeyDataStorePtr x509Store ;
1017
1018         xmlSecAssert2( mngr != NULL, -1 ) ;
1019         xmlSecAssert2( untrustedStore != NULL, -1 ) ;
1020
1021     x509Store = xmlSecKeysMngrGetDataStore( mngr, xmlSecMSCryptoX509StoreId);
1022         if( x509Store == NULL ) {
1023                 xmlSecError( XMLSEC_ERRORS_HERE ,
1024                         NULL ,
1025                         "xmlSecKeysMngrGetDataStore" ,
1026                         XMLSEC_ERRORS_R_XMLSEC_FAILED ,
1027                         XMLSEC_ERRORS_NO_MESSAGE ) ;
1028                 return(-1);
1029         }
1030
1031         if( xmlSecMSCryptoX509StoreAdoptUntrustedStore( x509Store, untrustedStore ) < 0) {
1032                 xmlSecError( XMLSEC_ERRORS_HERE ,
1033                         xmlSecErrorsSafeString( xmlSecKeyDataStoreGetName( x509Store ) ) ,
1034                         "xmlSecMSCryptoX509StoreAdoptKeyStore" ,
1035                         XMLSEC_ERRORS_R_XMLSEC_FAILED ,
1036                         XMLSEC_ERRORS_NO_MESSAGE ) ;
1037                 return(-1);
1038         }
1039
1040         return(0) ;
1041 }
1042
1043 #endif /* XMLSEC_NO_X509 */
1044
1045 /**
1046  * xmlSecMSCryptoAppDefaultKeysMngrInit:
1047  * @mngr:               the pointer to keys manager.
1048  *
1049  * Initializes @mngr with simple keys store #xmlSecSimpleKeysStoreId
1050  * and a default MSCrypto crypto key data stores.
1051  *
1052  * Returns: 0 on success or a negative value otherwise.
1053  */ 
1054 int
1055 xmlSecMSCryptoAppDefaultKeysMngrInit(xmlSecKeysMngrPtr mngr) {
1056     int ret;
1057     
1058     xmlSecAssert2(mngr != NULL, -1);
1059
1060     /* create MSCrypto keys store if needed */        
1061     if(xmlSecKeysMngrGetKeysStore(mngr) == NULL) {
1062         xmlSecKeyStorePtr keysStore;
1063
1064         keysStore = xmlSecKeyStoreCreate(xmlSecMSCryptoKeysStoreId);
1065         if(keysStore == NULL) {
1066             xmlSecError(XMLSEC_ERRORS_HERE,
1067                         NULL,
1068                         "xmlSecKeyStoreCreate",
1069                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
1070                         "xmlSecMSCryptoKeysStoreId");
1071             return(-1);
1072         }
1073         
1074         ret = xmlSecKeysMngrAdoptKeysStore(mngr, keysStore);
1075         if(ret < 0) {
1076             xmlSecError(XMLSEC_ERRORS_HERE,
1077                         NULL,
1078                         "xmlSecKeysMngrAdoptKeysStore",
1079                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
1080                         XMLSEC_ERRORS_NO_MESSAGE);
1081             xmlSecKeyStoreDestroy(keysStore);
1082             return(-1);        
1083         }
1084     }
1085
1086     ret = xmlSecMSCryptoKeysMngrInit(mngr);    
1087     if(ret < 0) {
1088         xmlSecError(XMLSEC_ERRORS_HERE,
1089                         NULL,
1090                         "xmlSecMSCryptoKeysMngrInit",
1091                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
1092                         XMLSEC_ERRORS_NO_MESSAGE);
1093         return(-1); 
1094     }
1095     
1096     mngr->getKey = xmlSecKeysMngrGetKey;
1097     return(0);
1098 }
1099
1100 /**
1101  * xmlSecMSCryptoAppDefaultKeysMngrAdoptKey:
1102  * @mngr:               the pointer to keys manager.
1103  * @key:                the pointer to key.
1104  *
1105  * Adds @key to the keys manager @mngr created with #xmlSecMSCryptoAppDefaultKeysMngrInit
1106  * function.
1107  *  
1108  * Returns: 0 on success or a negative value otherwise.
1109  */ 
1110 int 
1111 xmlSecMSCryptoAppDefaultKeysMngrAdoptKey(xmlSecKeysMngrPtr mngr, xmlSecKeyPtr key) {
1112     xmlSecKeyStorePtr store;
1113     int ret;
1114     
1115     xmlSecAssert2(mngr != NULL, -1);
1116     xmlSecAssert2(key != NULL, -1);
1117     
1118     store = xmlSecKeysMngrGetKeysStore(mngr);
1119     if(store == NULL) {
1120         xmlSecError(XMLSEC_ERRORS_HERE,
1121                     NULL,
1122                     "xmlSecKeysMngrGetKeysStore",
1123                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1124                     XMLSEC_ERRORS_NO_MESSAGE);
1125         return(-1);
1126     }
1127     
1128     ret = xmlSecMSCryptoKeysStoreAdoptKey(store, key);
1129     if(ret < 0) {
1130         xmlSecError(XMLSEC_ERRORS_HERE,
1131                     NULL,
1132                     "xmlSecMSCryptoKeysStoreAdoptKey",
1133                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1134                     XMLSEC_ERRORS_NO_MESSAGE);
1135         return(-1);
1136     }
1137     
1138     return(0);
1139 }
1140
1141 /**
1142  * xmlSecMSCryptoAppDefaultKeysMngrLoad:
1143  * @mngr:               the pointer to keys manager.
1144  * @uri:                the uri.
1145  *
1146  * Loads XML keys file from @uri to the keys manager @mngr created 
1147  * with #xmlSecMSCryptoAppDefaultKeysMngrInit function.
1148  *  
1149  * Returns: 0 on success or a negative value otherwise.
1150  */ 
1151 int 
1152 xmlSecMSCryptoAppDefaultKeysMngrLoad(xmlSecKeysMngrPtr mngr, const char* uri) {
1153     xmlSecKeyStorePtr store;
1154     int ret;
1155     
1156     xmlSecAssert2(mngr != NULL, -1);
1157     xmlSecAssert2(uri != NULL, -1);
1158     
1159     store = xmlSecKeysMngrGetKeysStore(mngr);
1160     if(store == NULL) {
1161         xmlSecError(XMLSEC_ERRORS_HERE,
1162                     NULL,
1163                     "xmlSecKeysMngrGetKeysStore",
1164                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1165                     XMLSEC_ERRORS_NO_MESSAGE);
1166         return(-1);
1167     }
1168     
1169     ret = xmlSecMSCryptoKeysStoreLoad(store, uri, mngr);
1170     if(ret < 0) {
1171         xmlSecError(XMLSEC_ERRORS_HERE,
1172                     NULL,
1173                     "xmlSecMSCryptoKeysStoreLoad",
1174                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
1175                     "uri=%s", xmlSecErrorsSafeString(uri));
1176         return(-1);
1177     }
1178     
1179     return(0);
1180 }
1181
1182 /**
1183  * xmlSecMSCryptoAppDefaultKeysMngrSave:
1184  * @mngr:               the pointer to keys manager.
1185  * @filename:   the destination filename.
1186  * @type:               the type of keys to save (public/private/symmetric).
1187  *
1188  * Saves keys from @mngr to  XML keys file.
1189  *  
1190  * Returns: 0 on success or a negative value otherwise.
1191  */ 
1192 int 
1193 xmlSecMSCryptoAppDefaultKeysMngrSave(xmlSecKeysMngrPtr mngr, const char* filename, xmlSecKeyDataType type) {
1194     xmlSecKeyStorePtr store;
1195     int ret;
1196     
1197     xmlSecAssert2(mngr != NULL, -1);
1198     xmlSecAssert2(filename != NULL, -1);
1199     
1200     store = xmlSecKeysMngrGetKeysStore(mngr);
1201     if(store == NULL) {
1202         xmlSecError(XMLSEC_ERRORS_HERE,
1203                         NULL,
1204                         "xmlSecKeysMngrGetKeysStore",
1205                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
1206                         XMLSEC_ERRORS_NO_MESSAGE);
1207         return(-1);
1208     }
1209     
1210     ret = xmlSecMSCryptoKeysStoreSave(store, filename, type);
1211     if(ret < 0) {
1212         xmlSecError(XMLSEC_ERRORS_HERE,
1213                         NULL,
1214                         "xmlSecMSCryptoKeysStoreSave",
1215                         XMLSEC_ERRORS_R_XMLSEC_FAILED,
1216                         "filename%s", xmlSecErrorsSafeString(filename));
1217         return(-1);
1218     }
1219     
1220     return(0);
1221 }
1222
1223 /**
1224  * xmlSecMSCryptoAppDefaultKeysMngrPrivateKeyLoad:
1225  * @mngr:               the pointer to keys manager.
1226  * @hKey:       the key handle.
1227  *  
1228  * Adds private key @hKey to the keys manager @mngr.
1229  * 
1230  * Returns: 0 on success or a negative value otherwise.
1231  */ 
1232 int
1233 xmlSecMSCryptoAppDefaultKeysMngrPrivateKeyLoad(xmlSecKeysMngrPtr mngr, HCRYPTKEY hKey) {
1234     xmlSecAssert2(mngr != NULL, -1);
1235     xmlSecAssert2(hKey != 0, -1);
1236
1237     /* TODO */
1238     return(0);
1239 }
1240
1241 /**
1242  * xmlSecMSCryptoAppDefaultKeysMngrPublicKeyLoad:
1243  * @mngr:               the pointer to keys manager.
1244  * @hKey:       the key handle.
1245  *  
1246  * Adds public key @hKey to the keys manager @mngr.
1247  * 
1248  * Returns: 0 on success or a negative value otherwise.
1249  */ 
1250 int 
1251 xmlSecMSCryptoAppDefaultKeysMngrPublicKeyLoad(xmlSecKeysMngrPtr mngr, HCRYPTKEY hKey) {
1252     xmlSecAssert2(mngr != NULL, -1);
1253     xmlSecAssert2(hKey != 0, -1);
1254
1255     /* TODO */
1256     return(0);
1257 }
1258
1259 /**
1260  * xmlSecMSCryptoAppDefaultKeysMngrSymKeyLoad:
1261  * @mngr:               the pointer to keys manager.
1262  * @hKey:       the key handle.
1263  *  
1264  * Adds symmetric key @hKey to the keys manager @mngr.
1265  * 
1266  * Returns: 0 on success or a negative value otherwise.
1267  */ 
1268 int 
1269 xmlSecMSCryptoAppDefaultKeysMngrSymKeyLoad(xmlSecKeysMngrPtr mngr, HCRYPTKEY hKey) {
1270     xmlSecAssert2(mngr != NULL, -1);
1271     xmlSecAssert2(hKey != 0, -1);
1272
1273     /* TODO */
1274     return(0);
1275 }
1276
1277 /**
1278  * xmlSecMSCryptoAppGetDefaultPwdCallback:
1279  *
1280  * Gets default password callback.
1281  *
1282  * Returns: default password callback.
1283  */
1284 void*
1285 xmlSecMSCryptoAppGetDefaultPwdCallback(void) {
1286     return(NULL);
1287 }
1288