202c9f14463b7102b2fcac34eb786ecbf7d8258a
[shibboleth/cpp-xmltooling.git] / xmltooling / XMLToolingConfig.cpp
1 /*
2  *  Copyright 2001-2010 Internet2
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * XMLToolingConfig.cpp
19  *
20  * Library configuration.
21  */
22
23 #include "internal.h"
24 #include "exceptions.h"
25 #include "logging.h"
26 #include "XMLToolingConfig.h"
27 #include "encryption/Encryption.h"
28 #include "encryption/Encrypter.h"
29 #include "impl/UnknownElement.h"
30 #include "io/HTTPResponse.h"
31 #include "security/TrustEngine.h"
32 #include "security/OpenSSLCryptoX509CRL.h"
33 #include "security/CredentialResolver.h"
34 #include "security/KeyInfoResolver.h"
35 #include "signature/KeyInfo.h"
36 #include "signature/Signature.h"
37 #include "soap/SOAP.h"
38 #include "util/NDC.h"
39 #include "util/PathResolver.h"
40 #include "util/ReplayCache.h"
41 #include "util/StorageService.h"
42 #include "util/TemplateEngine.h"
43 #include "util/Threads.h"
44 #include "util/URLEncoder.h"
45 #include "validation/ValidatorSuite.h"
46
47 #ifdef HAVE_DLFCN_H
48 # include <dlfcn.h>
49 #endif
50
51 #include <stdexcept>
52 #if defined(XMLTOOLING_LOG4SHIB)
53 # include <log4shib/PropertyConfigurator.hh>
54 # include <log4shib/OstreamAppender.hh>
55 #elif defined(XMLTOOLING_LOG4CPP)
56 # include <log4cpp/PropertyConfigurator.hh>
57 # include <log4cpp/OstreamAppender.hh>
58 #endif
59 #include <xercesc/util/PlatformUtils.hpp>
60 #include <xercesc/util/XMLUniDefs.hpp>
61 #ifndef XMLTOOLING_NO_XMLSEC
62 # include <curl/curl.h>
63 # include <openssl/err.h>
64 # include <xsec/framework/XSECAlgorithmMapper.hpp>
65 # include <xsec/framework/XSECException.hpp>
66 # include <xsec/framework/XSECProvider.hpp>
67 # include <xsec/transformers/TXFMBase.hpp>
68 #endif
69
70 using namespace soap11;
71 using namespace xmltooling::logging;
72 using namespace xmltooling;
73 using namespace xercesc;
74 using namespace std;
75
76
77 DECL_XMLTOOLING_EXCEPTION_FACTORY(XMLParserException,xmltooling);
78 DECL_XMLTOOLING_EXCEPTION_FACTORY(XMLObjectException,xmltooling);
79 DECL_XMLTOOLING_EXCEPTION_FACTORY(MarshallingException,xmltooling);
80 DECL_XMLTOOLING_EXCEPTION_FACTORY(UnmarshallingException,xmltooling);
81 DECL_XMLTOOLING_EXCEPTION_FACTORY(UnknownElementException,xmltooling);
82 DECL_XMLTOOLING_EXCEPTION_FACTORY(UnknownAttributeException,xmltooling);
83 DECL_XMLTOOLING_EXCEPTION_FACTORY(UnknownExtensionException,xmltooling);
84 DECL_XMLTOOLING_EXCEPTION_FACTORY(ValidationException,xmltooling);
85 DECL_XMLTOOLING_EXCEPTION_FACTORY(IOException,xmltooling);
86
87 #ifndef XMLTOOLING_NO_XMLSEC
88 using namespace xmlencryption;
89 using namespace xmlsignature;
90     DECL_XMLTOOLING_EXCEPTION_FACTORY(XMLSecurityException,xmltooling);
91     DECL_XMLTOOLING_EXCEPTION_FACTORY(SignatureException,xmlsignature);
92     DECL_XMLTOOLING_EXCEPTION_FACTORY(EncryptionException,xmlencryption);
93 #endif
94
95 namespace {
96     static XMLToolingInternalConfig g_config;
97 #ifndef XMLTOOLING_NO_XMLSEC
98     static vector<Mutex*> g_openssl_locks;
99
100     extern "C" void openssl_locking_callback(int mode,int n,const char *file,int line)
101     {
102         if (mode & CRYPTO_LOCK)
103             g_openssl_locks[n]->lock();
104         else
105             g_openssl_locks[n]->unlock();
106     }
107
108 # ifndef WIN32
109     extern "C" unsigned long openssl_thread_id(void)
110     {
111         return (unsigned long)(pthread_self());
112     }
113 # endif
114
115 # ifdef XMLTOOLING_XMLSEC_DEBUGLOGGING
116     class TXFMOutputLog : public TXFMBase {
117             TXFMOutputLog();
118     public:
119         TXFMOutputLog(DOMDocument* doc) : TXFMBase(doc), m_log(Category::getInstance(XMLTOOLING_LOGCAT".Signature.Debugger")) {
120             input = nullptr;
121         }
122         ~TXFMOutputLog() {
123             m_log.debug("\n----- END SIGNATURE DEBUG -----\n");
124         }
125
126             void setInput(TXFMBase *newInput) {
127                 input = newInput;
128                 if (newInput->getOutputType() != TXFMBase::BYTE_STREAM)
129                         throw XSECException(XSECException::TransformInputOutputFail, "OutputLog transform requires BYTE_STREAM input");
130                 keepComments = input->getCommentsStatus();
131             m_log.debug("\n----- BEGIN SIGNATURE DEBUG -----\n");
132         }
133
134             TXFMBase::ioType getInputType() {
135             return TXFMBase::BYTE_STREAM;
136         }
137             TXFMBase::ioType getOutputType() {
138             return TXFMBase::BYTE_STREAM;
139         }
140             TXFMBase::nodeType getNodeType() {
141             return TXFMBase::DOM_NODE_NONE;
142         }
143
144             unsigned int readBytes(XMLByte * const toFill, const unsigned int maxToFill) {
145                 unsigned int sz = input->readBytes(toFill, maxToFill);
146             m_log.debug(string(reinterpret_cast<char* const>(toFill), sz));
147                 return sz;
148         }
149
150             DOMDocument* getDocument() {
151             return nullptr;
152         }
153             DOMNode* getFragmentNode() {
154             return nullptr;
155         }
156             const XMLCh* getFragmentId() {
157             return nullptr;
158         }
159         
160     private:
161         Category& m_log;
162     };
163
164     TXFMBase* TXFMOutputLogFactory(DOMDocument* doc) {
165         if (Category::getInstance(XMLTOOLING_LOGCAT".Signature.Debugger").isDebugEnabled())
166             return new TXFMOutputLog(doc);
167         return nullptr;
168     }
169 # endif
170
171 #endif
172
173 #ifdef WIN32
174     BOOL LogEvent(
175         LPCSTR  lpUNCServerName,
176         WORD  wType,
177         DWORD  dwEventID,
178         PSID  lpUserSid,
179         LPCSTR  message)
180     {
181         LPCSTR  messages[] = {message, nullptr};
182
183         HANDLE hElog = RegisterEventSource(lpUNCServerName, "OpenSAML XMLTooling Library");
184         BOOL res = ReportEvent(hElog, wType, 0, dwEventID, lpUserSid, 1, 0, messages, nullptr);
185         return (DeregisterEventSource(hElog) && res);
186     }
187 #endif
188 }
189
190 XMLToolingConfig& XMLToolingConfig::getConfig()
191 {
192     return g_config;
193 }
194
195 XMLToolingInternalConfig& XMLToolingInternalConfig::getInternalConfig()
196 {
197     return g_config;
198 }
199
200 #ifndef XMLTOOLING_NO_XMLSEC
201 XMLToolingConfig::XMLToolingConfig()
202     : m_keyInfoResolver(nullptr), m_replayCache(nullptr), m_pathResolver(nullptr), m_templateEngine(nullptr), m_urlEncoder(nullptr), clock_skew_secs(180)
203 #else
204 XMLToolingConfig::XMLToolingConfig()
205     : m_pathResolver(nullptr), m_templateEngine(nullptr), m_urlEncoder(nullptr), clock_skew_secs(180)
206 #endif
207 {
208 }
209
210 XMLToolingConfig::~XMLToolingConfig()
211 {
212 }
213
214 bool XMLToolingInternalConfig::log_config(const char* config)
215 {
216     try {
217         if (!config || !*config)
218             config=getenv("XMLTOOLING_LOG_CONFIG");
219         if (!config || !*config)
220             config="WARN";
221
222         bool level=false;
223         Category& root = Category::getRoot();
224         if (!strcmp(config,"DEBUG")) {
225             root.setPriority(Priority::DEBUG);
226             level=true;
227         }
228         else if (!strcmp(config,"INFO")) {
229             root.setPriority(Priority::INFO);
230             level=true;
231         }
232         else if (!strcmp(config,"NOTICE")) {
233             root.setPriority(Priority::NOTICE);
234             level=true;
235         }
236         else if (!strcmp(config,"WARN")) {
237             root.setPriority(Priority::WARN);
238             level=true;
239         }
240         else if (!strcmp(config,"ERROR")) {
241             root.setPriority(Priority::ERROR);
242             level=true;
243         }
244         else if (!strcmp(config,"CRIT")) {
245             root.setPriority(Priority::CRIT);
246             level=true;
247         }
248         else if (!strcmp(config,"ALERT")) {
249             root.setPriority(Priority::ALERT);
250             level=true;
251         }
252         else if (!strcmp(config,"EMERG")) {
253             root.setPriority(Priority::EMERG);
254             level=true;
255         }
256         else if (!strcmp(config,"FATAL")) {
257             root.setPriority(Priority::FATAL);
258             level=true;
259         }
260         if (level) {
261             root.setAppender(new OstreamAppender("default",&cerr));
262         }
263         else {
264             string path(config);
265             PropertyConfigurator::configure(m_pathResolver ? m_pathResolver->resolve(path, PathResolver::XMLTOOLING_CFG_FILE) : path);
266         }
267     }
268     catch (const ConfigureFailure& e) {
269         string msg = string("failed to configure logging: ") + e.what();
270         Category::getInstance(XMLTOOLING_LOGCAT".Logging").crit(msg);
271 #ifdef WIN32
272         LogEvent(nullptr, EVENTLOG_ERROR_TYPE, 2100, nullptr, msg.c_str());
273 #endif
274         return false;
275     }
276
277     return true;
278 }
279
280 #ifndef XMLTOOLING_LITE
281 const KeyInfoResolver* XMLToolingConfig::getKeyInfoResolver() const
282 {
283     return m_keyInfoResolver;
284 }
285
286 ReplayCache* XMLToolingConfig::getReplayCache() const
287 {
288     return m_replayCache;
289 }
290
291 void XMLToolingConfig::setKeyInfoResolver(xmltooling::KeyInfoResolver *keyInfoResolver)
292 {
293     delete m_keyInfoResolver;
294     m_keyInfoResolver = keyInfoResolver;
295 }
296
297 void XMLToolingConfig::setReplayCache(ReplayCache* replayCache)
298 {
299     delete m_replayCache;
300     m_replayCache = replayCache;
301 }
302 #endif
303
304 PathResolver* XMLToolingConfig::getPathResolver() const
305 {
306     return m_pathResolver;
307 }
308
309 TemplateEngine* XMLToolingConfig::getTemplateEngine() const
310 {
311     return m_templateEngine;
312 }
313
314 const URLEncoder* XMLToolingConfig::getURLEncoder() const
315 {
316     return m_urlEncoder;
317 }
318
319 void XMLToolingConfig::setPathResolver(PathResolver* pathResolver)
320 {
321     delete m_pathResolver;
322     m_pathResolver = pathResolver;
323 }
324
325 void XMLToolingConfig::setTemplateEngine(TemplateEngine* templateEngine)
326 {
327     delete m_templateEngine;
328     m_templateEngine = templateEngine;
329 }
330
331 void XMLToolingConfig::setURLEncoder(URLEncoder* urlEncoder)
332 {
333     delete m_urlEncoder;
334     m_urlEncoder = urlEncoder;
335 }
336
337 bool XMLToolingInternalConfig::init()
338 {
339 #ifdef _DEBUG
340     xmltooling::NDC ndc("init");
341 #endif
342     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLToolingConfig");
343     try {
344         log.debug("library initialization started");
345
346 #ifndef XMLTOOLING_NO_XMLSEC
347         if (curl_global_init(CURL_GLOBAL_ALL)) {
348             log.fatal("failed to initialize libcurl, OpenSSL, or Winsock");
349             return false;
350         }
351         log.debug("libcurl %s initialization complete", LIBCURL_VERSION);
352 #endif
353
354         XMLPlatformUtils::Initialize();
355         log.debug("Xerces %s initialization complete", XERCES_FULLVERSIONDOT);
356
357 #ifndef XMLTOOLING_NO_XMLSEC
358         XSECPlatformUtils::Initialise();
359 # ifdef XMLTOOLING_XMLSEC_DEBUGLOGGING
360         XSECPlatformUtils::SetReferenceLoggingSink(TXFMOutputLogFactory);
361 # endif
362         m_xsecProvider=new XSECProvider();
363         log.debug("XML-Security %s initialization complete", XSEC_FULLVERSIONDOT);
364 #endif
365
366         m_parserPool=new ParserPool();
367         m_validatingPool=new ParserPool(true,true);
368         m_lock=XMLPlatformUtils::makeMutex();
369
370         // Load catalogs from path.
371         if (!catalog_path.empty()) {
372             char* catpath=strdup(catalog_path.c_str());
373             char* sep=nullptr;
374             char* start=catpath;
375             while (start && *start) {
376                 sep=strchr(start,PATH_SEPARATOR_CHAR);
377                 if (sep)
378                     *sep=0;
379                 auto_ptr_XMLCh temp(start);
380                 m_validatingPool->loadCatalog(temp.get());
381                 start = sep ? sep + 1 : nullptr;
382             }
383             free(catpath);
384         }
385
386         // default registrations
387         XMLObjectBuilder::registerDefaultBuilder(new UnknownElementBuilder());
388
389         registerSOAPClasses();
390
391         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLParserException,xmltooling);
392         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLObjectException,xmltooling);
393         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(MarshallingException,xmltooling);
394         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(UnmarshallingException,xmltooling);
395         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(UnknownElementException,xmltooling);
396         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(UnknownAttributeException,xmltooling);
397         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(ValidationException,xmltooling);
398         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(IOException,xmltooling);
399
400 #ifndef XMLTOOLING_NO_XMLSEC
401         XMLObjectBuilder::registerBuilder(QName(xmlconstants::XMLSIG_NS,Signature::LOCAL_NAME),new SignatureBuilder());
402         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLSecurityException,xmltooling);
403         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(SignatureException,xmlsignature);
404         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(EncryptionException,xmlencryption);
405         registerKeyInfoClasses();
406         registerEncryptionClasses();
407         registerKeyInfoResolvers();
408         registerCredentialResolvers();
409         registerTrustEngines();
410         registerXMLAlgorithms();
411         registerSOAPTransports();
412         initSOAPTransports();
413         registerStorageServices();
414         m_keyInfoResolver = KeyInfoResolverManager.newPlugin(INLINE_KEYINFO_RESOLVER,nullptr);
415 #endif
416
417         m_pathResolver = new PathResolver();
418         m_urlEncoder = new URLEncoder();
419
420         HTTPResponse::getAllowedSchemes().push_back("https");
421         HTTPResponse::getAllowedSchemes().push_back("http");
422
423         // Register xml:id as an ID attribute.
424         static const XMLCh xmlid[] = UNICODE_LITERAL_2(i,d);
425         AttributeExtensibleXMLObject::registerIDAttribute(QName(xmlconstants::XML_NS, xmlid));
426     }
427     catch (const xercesc::XMLException&) {
428         log.fatal("caught exception while initializing Xerces");
429 #ifndef XMLTOOLING_NO_XMLSEC
430         curl_global_cleanup();
431 #endif
432         return false;
433     }
434
435 #ifndef XMLTOOLING_NO_XMLSEC
436     // Set up OpenSSL locking.
437     for (int i=0; i<CRYPTO_num_locks(); i++)
438         g_openssl_locks.push_back(Mutex::create());
439     CRYPTO_set_locking_callback(openssl_locking_callback);
440 # ifndef WIN32
441     CRYPTO_set_id_callback(openssl_thread_id);
442 # endif
443 #endif
444
445     log.info("%s library initialization complete", PACKAGE_STRING);
446     return true;
447 }
448
449 void XMLToolingInternalConfig::term()
450 {
451 #ifndef XMLTOOLING_NO_XMLSEC
452     CRYPTO_set_locking_callback(nullptr);
453     for_each(g_openssl_locks.begin(), g_openssl_locks.end(), xmltooling::cleanup<Mutex>());
454     g_openssl_locks.clear();
455 #endif
456
457     SchemaValidators.destroyValidators();
458     XMLObjectBuilder::destroyBuilders();
459     XMLToolingException::deregisterFactories();
460     AttributeExtensibleXMLObject::deregisterIDAttributes();
461
462 #ifndef XMLTOOLING_NO_XMLSEC
463     StorageServiceManager.deregisterFactories();
464     termSOAPTransports();
465     SOAPTransportManager.deregisterFactories();
466     TrustEngineManager.deregisterFactories();
467     CredentialResolverManager.deregisterFactories();
468     KeyInfoResolverManager.deregisterFactories();
469     m_algorithmMap.clear();
470
471     delete m_keyInfoResolver;
472     m_keyInfoResolver = nullptr;
473
474     delete m_replayCache;
475     m_replayCache = nullptr;
476 #endif
477
478     delete m_pathResolver;
479     m_pathResolver = nullptr;
480
481     delete m_templateEngine;
482     m_templateEngine = nullptr;
483
484     delete m_urlEncoder;
485     m_urlEncoder = nullptr;
486
487     for (vector<void*>::reverse_iterator i=m_libhandles.rbegin(); i!=m_libhandles.rend(); i++) {
488 #if defined(WIN32)
489         FARPROC fn=GetProcAddress(static_cast<HMODULE>(*i),"xmltooling_extension_term");
490         if (fn)
491             fn();
492         FreeLibrary(static_cast<HMODULE>(*i));
493 #elif defined(HAVE_DLFCN_H)
494         void (*fn)()=(void (*)())dlsym(*i,"xmltooling_extension_term");
495         if (fn)
496             fn();
497         dlclose(*i);
498 #else
499 # error "Don't know about dynamic loading on this platform!"
500 #endif
501     }
502     m_libhandles.clear();
503
504     delete m_parserPool;
505     m_parserPool=nullptr;
506     delete m_validatingPool;
507     m_validatingPool=nullptr;
508
509 #ifndef XMLTOOLING_NO_XMLSEC
510     delete m_xsecProvider;
511     m_xsecProvider=nullptr;
512     XSECPlatformUtils::Terminate();
513 #endif
514
515     XMLPlatformUtils::closeMutex(m_lock);
516     m_lock=nullptr;
517     XMLPlatformUtils::Terminate();
518
519 #ifndef XMLTOOLING_NO_XMLSEC
520     curl_global_cleanup();
521 #endif
522 #ifdef _DEBUG
523     xmltooling::NDC ndc("term");
524 #endif
525    Category::getInstance(XMLTOOLING_LOGCAT".XMLToolingConfig").info("%s library shutdown complete", PACKAGE_STRING);
526 }
527
528 Lockable* XMLToolingInternalConfig::lock()
529 {
530     xercesc::XMLPlatformUtils::lockMutex(m_lock);
531     return this;
532 }
533
534 void XMLToolingInternalConfig::unlock()
535 {
536     xercesc::XMLPlatformUtils::unlockMutex(m_lock);
537 }
538
539 bool XMLToolingInternalConfig::load_library(const char* path, void* context)
540 {
541 #ifdef _DEBUG
542     xmltooling::NDC ndc("LoadLibrary");
543 #endif
544     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLToolingConfig");
545     log.info("loading extension: %s", path);
546
547     Locker locker(this);
548
549     string resolved(path);
550     m_pathResolver->resolve(resolved, PathResolver::XMLTOOLING_LIB_FILE);
551
552 #if defined(WIN32)
553     HMODULE handle=nullptr;
554     for (string::iterator i = resolved.begin(); i != resolved.end(); ++i)
555         if (*i == '/')
556             *i = '\\';
557
558     UINT em=SetErrorMode(SEM_FAILCRITICALERRORS);
559     try {
560         handle=LoadLibraryEx(resolved.c_str(),nullptr,LOAD_WITH_ALTERED_SEARCH_PATH);
561         if (!handle)
562              handle=LoadLibraryEx(resolved.c_str(),nullptr,0);
563         if (!handle)
564             throw runtime_error(string("unable to load extension library: ") + resolved);
565         FARPROC fn=GetProcAddress(handle,"xmltooling_extension_init");
566         if (!fn)
567             throw runtime_error(string("unable to locate xmltooling_extension_init entry point: ") + resolved);
568         if (reinterpret_cast<int(*)(void*)>(fn)(context)!=0)
569             throw runtime_error(string("detected error in xmltooling_extension_init: ") + resolved);
570         SetErrorMode(em);
571     }
572     catch(exception&) {
573         if (handle)
574             FreeLibrary(handle);
575         SetErrorMode(em);
576         throw;
577     }
578
579 #elif defined(HAVE_DLFCN_H)
580     void* handle=dlopen(resolved.c_str(),RTLD_LAZY);
581     if (!handle)
582         throw runtime_error(string("unable to load extension library '") + resolved + "': " + dlerror());
583     int (*fn)(void*)=(int (*)(void*))(dlsym(handle,"xmltooling_extension_init"));
584     if (!fn) {
585         dlclose(handle);
586         throw runtime_error(
587             string("unable to locate xmltooling_extension_init entry point in '") + resolved + "': " +
588                 (dlerror() ? dlerror() : "unknown error")
589             );
590     }
591     try {
592         if (fn(context)!=0)
593             throw runtime_error(string("detected error in xmltooling_extension_init in ") + resolved);
594     }
595     catch(exception&) {
596         if (handle)
597             dlclose(handle);
598         throw;
599     }
600 #else
601 # error "Don't know about dynamic loading on this platform!"
602 #endif
603     m_libhandles.push_back(handle);
604     log.info("loaded extension: %s", resolved.c_str());
605     return true;
606 }
607
608 #ifndef XMLTOOLING_NO_XMLSEC
609
610 void xmltooling::log_openssl()
611 {
612     const char* file;
613     const char* data;
614     int flags,line;
615
616     unsigned long code=ERR_get_error_line_data(&file,&line,&data,&flags);
617     while (code) {
618         Category& log=Category::getInstance("OpenSSL");
619         log.errorStream() << "error code: " << code << " in " << file << ", line " << line << logging::eol;
620         if (data && (flags & ERR_TXT_STRING))
621             log.errorStream() << "error data: " << data << logging::eol;
622         code=ERR_get_error_line_data(&file,&line,&data,&flags);
623     }
624 }
625
626 XSECCryptoX509CRL* XMLToolingInternalConfig::X509CRL() const
627 {
628     return new OpenSSLCryptoX509CRL();
629 }
630
631 pair<const char*,unsigned int> XMLToolingInternalConfig::mapXMLAlgorithmToKeyAlgorithm(const XMLCh* xmlAlgorithm) const
632 {
633     algmap_t::const_iterator i = m_algorithmMap.find(xmlAlgorithm);
634     if (i == m_algorithmMap.end())
635         return pair<const char*,unsigned int>(nullptr, 0);
636     return make_pair(i->second.first.c_str(), i->second.second);
637 }
638
639 void XMLToolingInternalConfig::registerXMLAlgorithm(const XMLCh* xmlAlgorithm, const char* keyAlgorithm, unsigned int size)
640 {
641     m_algorithmMap[xmlAlgorithm] = pair<string,unsigned int>(keyAlgorithm, size);
642 }
643
644 bool XMLToolingInternalConfig::isXMLAlgorithmSupported(const XMLCh* xmlAlgorithm)
645 {
646     try {
647         if (XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(xmlAlgorithm))
648             return true;
649     }
650     catch (XSECException&) {
651     }
652     return false;
653 }
654
655 void XMLToolingInternalConfig::registerXMLAlgorithms()
656 {
657     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIRSA_MD5, "RSA", 0);
658     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIRSA_SHA1, "RSA", 0);
659     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIRSA_SHA224, "RSA", 0);
660     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIRSA_SHA256, "RSA", 0);
661     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIRSA_SHA384, "RSA", 0);
662     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIRSA_SHA512, "RSA", 0);
663
664     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIRSA_1_5, "RSA", 0);
665     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1, "RSA", 0);
666
667     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIDSA_SHA1, "DSA", 0);
668
669     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIECDSA_SHA1, "EC", 0);
670     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIECDSA_SHA256, "EC", 0);
671     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIECDSA_SHA384, "EC", 0);
672     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIECDSA_SHA512, "EC", 0);
673
674     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIHMAC_SHA1, "HMAC", 0);
675     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIHMAC_SHA224, "HMAC", 0);
676     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIHMAC_SHA256, "HMAC", 0);
677     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIHMAC_SHA384, "HMAC", 0);
678     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIHMAC_SHA512, "HMAC", 0);
679
680     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURI3DES_CBC, "DESede", 192);
681     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIKW_3DES, "DESede", 192);
682
683     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIAES128_CBC, "AES", 128);
684     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIKW_AES128, "AES", 128);
685
686     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIAES192_CBC, "AES", 192);
687     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIKW_AES192, "AES", 192);
688
689     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIAES256_CBC, "AES", 256);
690     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIKW_AES256, "AES", 256);
691 }
692
693 #endif
694
695 #ifdef WIN32
696
697 extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID)
698 {
699     if (fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH)
700         ThreadKey::onDetach();
701     return TRUE;
702 }
703
704 #endif