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