From: scantor Date: Thu, 5 Jul 2012 20:52:16 +0000 (+0000) Subject: https://issues.shibboleth.net/jira/browse/SSPCPP-366 X-Git-Tag: 2.5.0~35 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fsp.git;a=commitdiff_plain;h=813888f7e2e308b5d90166e85d571ea9c361b749 https://issues.shibboleth.net/jira/browse/SSPCPP-366 git-svn-id: https://svn.shibboleth.net/cpp-sp/branches/REL_2@3723 cb58f699-b61c-0410-a6fe-9272a202ed29 --- diff --git a/shibsp/handler/impl/MetadataGenerator.cpp b/shibsp/handler/impl/MetadataGenerator.cpp index 5c912aa..0ccf892 100644 --- a/shibsp/handler/impl/MetadataGenerator.cpp +++ b/shibsp/handler/impl/MetadataGenerator.cpp @@ -45,12 +45,14 @@ # include # include # include +# include # include # include # include # include # include # include +# include # include # include #endif @@ -61,6 +63,8 @@ using namespace shibsp; using namespace opensaml::saml2md; using namespace opensaml; using namespace xmlsignature; +using xmlencryption::EncryptionMethod; +using xmlencryption::EncryptionMethodBuilder; #endif using namespace xmltooling; using namespace boost; @@ -91,6 +95,39 @@ namespace shibsp { ) const; #ifndef SHIBSP_LITE + void registerEncryptionMethod(const XMLCh* alg) { + if (XMLToolingConfig::getConfig().isXMLAlgorithmSupported(alg, XMLToolingConfig::ALGTYPE_ENCRYPT) || + XMLToolingConfig::getConfig().isXMLAlgorithmSupported(alg, XMLToolingConfig::ALGTYPE_KEYENCRYPT) || + XMLToolingConfig::getConfig().isXMLAlgorithmSupported(alg, XMLToolingConfig::ALGTYPE_KEYAGREE)) { + // Non-default builder needed to override namespace/prefix. + if (!m_encryptionBuilder) + m_encryptionBuilder = XMLObjectBuilder::getBuilder(xmltooling::QName(samlconstants::SAML20MD_NS, EncryptionMethod::LOCAL_NAME)); + EncryptionMethod* em = dynamic_cast( + m_encryptionBuilder->buildObject( + samlconstants::SAML20MD_NS, EncryptionMethod::LOCAL_NAME, samlconstants::SAML20MD_PREFIX + ) + ); + em->setAlgorithm(alg); + m_encryptions.push_back(em); + } + } + + void registerDigestMethod(const XMLCh* alg) { + if (XMLToolingConfig::getConfig().isXMLAlgorithmSupported(alg, XMLToolingConfig::ALGTYPE_DIGEST)) { + DigestMethod* dm = DigestMethodBuilder::buildDigestMethod(); + dm->setAlgorithm(alg); + m_digests.push_back(dm); + } + } + + void registerSigningMethod(const XMLCh* alg) { + if (XMLToolingConfig::getConfig().isXMLAlgorithmSupported(alg, XMLToolingConfig::ALGTYPE_SIGN)) { + SigningMethod* sm = SigningMethodBuilder::buildSigningMethod(); + sm->setAlgorithm(alg); + m_signings.push_back(sm); + } + } + string m_salt; short m_http,m_https; vector m_bases; @@ -101,6 +138,10 @@ namespace shibsp { ptr_vector m_formats; ptr_vector m_reqAttrs; ptr_vector m_attrConsumers; + ptr_vector m_encryptions; + ptr_vector m_digests; + ptr_vector m_signings; + const XMLObjectBuilder* m_encryptionBuilder; #endif }; @@ -118,7 +159,7 @@ namespace shibsp { MetadataGenerator::MetadataGenerator(const DOMElement* e, const char* appId) : SecuredHandler(e, Category::getInstance(SHIBSP_LOGCAT".MetadataGenerator")) #ifndef SHIBSP_LITE - ,m_http(0), m_https(0) + ,m_http(0), m_https(0), m_encryptionBuilder(nullptr) #endif { string address(appId); @@ -126,7 +167,7 @@ MetadataGenerator::MetadataGenerator(const DOMElement* e, const char* appId) setAddress(address.c_str()); #ifndef SHIBSP_LITE - static XMLCh EndpointBase[] = UNICODE_LITERAL_12(E,n,d,p,o,i,n,t,B,a,s,e); + static XMLCh EndpointBase[] = UNICODE_LITERAL_12(E,n,d,p,o,i,n,t,B,a,s,e); pair salt = getString("salt"); if (salt.first) @@ -205,6 +246,27 @@ MetadataGenerator::MetadataGenerator(const DOMElement* e, const char* appId) m_log.warn("skipping duplicate EntityAttributes element"); } } + else { + EncryptionMethod* em = dynamic_cast(child.get()); + if (em) { + m_encryptions.push_back(em); + child.release(); + } + else { + DigestMethod* dm = dynamic_cast(child.get()); + if (dm) { + m_digests.push_back(dm); + child.release(); + } + else { + SigningMethod* sm = dynamic_cast(child.get()); + if (sm) { + m_signings.push_back(sm); + child.release(); + } + } + } + } } } } @@ -214,6 +276,58 @@ MetadataGenerator::MetadataGenerator(const DOMElement* e, const char* appId) } e = XMLHelper::getNextSiblingElement(e); } + + // Default in precedence rules for various algorithms. + if (m_encryptions.empty()) { +#ifdef XSEC_OPENSSL_HAVE_GCM + registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES128_GCM); + registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES192_GCM); + registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES256_GCM); +#endif +#ifdef XSEC_OPENSSL_HAVE_AES + registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES128_CBC); + registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES192_CBC); + registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES256_CBC); +#endif + registerEncryptionMethod(DSIGConstants::s_unicodeStrURI3DES_CBC); +#ifdef URI_ID_RSA_OAEP + registerEncryptionMethod(DSIGConstants::s_unicodeStrURIRSA_OAEP); +#endif + registerEncryptionMethod(DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1); + registerEncryptionMethod(DSIGConstants::s_unicodeStrURIRSA_1_5); + } + + if (m_digests.empty()) { + registerDigestMethod(DSIGConstants::s_unicodeStrURISHA512); + registerDigestMethod(DSIGConstants::s_unicodeStrURISHA384); + registerDigestMethod(DSIGConstants::s_unicodeStrURISHA256); + registerDigestMethod(DSIGConstants::s_unicodeStrURISHA224); + registerDigestMethod(DSIGConstants::s_unicodeStrURISHA1); + } + + if (m_signings.empty()) { +#ifdef XSEC_OPENSSL_HAVE_EC + registerSigningMethod(DSIGConstants::s_unicodeStrURIECDSA_SHA512); + registerSigningMethod(DSIGConstants::s_unicodeStrURIECDSA_SHA384); + registerSigningMethod(DSIGConstants::s_unicodeStrURIECDSA_SHA256); +# ifdef URI_ID_ECDSA_SHA224 + registerSigningMethod(DSIGConstants::s_unicodeStrURIECDSA_SHA224); +# endif +#endif + registerSigningMethod(DSIGConstants::s_unicodeStrURIRSA_SHA512); + registerSigningMethod(DSIGConstants::s_unicodeStrURIRSA_SHA384); + registerSigningMethod(DSIGConstants::s_unicodeStrURIRSA_SHA256); + +#ifdef URI_ID_DSA_SHA256 + registerSigningMethod(DSIGConstants::s_unicodeStrURIDSA_SHA256); +#endif + +#ifdef XSEC_OPENSSL_HAVE_EC + registerSigningMethod(DSIGConstants::s_unicodeStrURIECDSA_SHA1); +#endif + registerSigningMethod(DSIGConstants::s_unicodeStrURIRSA_SHA1); + registerSigningMethod(DSIGConstants::s_unicodeStrURIDSA_SHA1); + } #endif } @@ -316,6 +430,12 @@ pair MetadataGenerator::processMessage( entity.reset(EntityDescriptorBuilder::buildEntityDescriptor()); } + // We always have extensions for algorithm support. + if (!entity->getExtensions()) { + entity->setExtensions(ExtensionsBuilder::buildExtensions()); + entity->getExtensions()->addNamespace(Namespace(samlconstants::SAML20MD_ALGSUPPORT_NS, samlconstants::SAML20MD_ALGSUPPORT_PREFIX)); + } + if (!entity->getID()) { string hashinput = m_salt + relyingParty->getString("entityID").second; string hashed = '_' + SecurityHelper::doHash("SHA1", hashinput.c_str(), hashinput.length()); @@ -339,8 +459,6 @@ pair MetadataGenerator::processMessage( entity->getContactPersons().push_back(cp->cloneContactPerson()); if (m_entityAttrs) { - if (!entity->getExtensions()) - entity->setExtensions(ExtensionsBuilder::buildExtensions()); entity->getExtensions()->getUnknownXMLObjects().push_back(m_entityAttrs->cloneEntityAttributes()); } @@ -362,6 +480,13 @@ pair MetadataGenerator::processMessage( role->getExtensions()->getUnknownXMLObjects().push_back(m_uiinfo->cloneUIInfo()); } + if (!m_digests.empty() || !m_signings.empty()) { + for (ptr_vector::const_iterator dm = m_digests.begin(); dm != m_digests.end(); ++dm) + entity->getExtensions()->getUnknownXMLObjects().push_back(dm->cloneDigestMethod()); + for (ptr_vector::const_iterator sm = m_signings.begin(); sm != m_signings.end(); ++sm) + entity->getExtensions()->getUnknownXMLObjects().push_back(sm->cloneSigningMethod()); + } + for (ptr_vector::const_iterator acs = m_attrConsumers.begin(); acs != m_attrConsumers.end(); ++acs) role->getAttributeConsumingServices().push_back(acs->cloneAttributeConsumingService()); @@ -458,6 +583,10 @@ pair MetadataGenerator::processMessage( } } kd->setUse(use); + if (!use) { + for (ptr_vector::const_iterator em = m_encryptions.begin(); em != m_encryptions.end(); ++em) + kd->getEncryptionMethods().push_back(em->cloneEncryptionMethod()); + } role->getKeyDescriptors().push_back(kd); } } @@ -468,6 +597,8 @@ pair MetadataGenerator::processMessage( KeyDescriptor* kd = KeyDescriptorBuilder::buildKeyDescriptor(); kd->setUse(KeyDescriptor::KEYTYPE_ENCRYPTION); kd->setKeyInfo(kinfo); + for (ptr_vector::const_iterator em = m_encryptions.begin(); em != m_encryptions.end(); ++em) + kd->getEncryptionMethods().push_back(em->cloneEncryptionMethod()); role->getKeyDescriptors().push_back(kd); } }