X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fsignature%2FContentReference.cpp;h=a40fbc63b9760856ffe66347bec66dc29456ac28;hb=241fd6224c15cf6c9a09f17dc71bf9988016ba56;hp=8253be4a433eb84f2e788b1b9584a329dc09d32b;hpb=335291aa66a9f8eae1a4604aa3502ccc948841e9;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/signature/ContentReference.cpp b/saml/signature/ContentReference.cpp index 8253be4..a40fbc6 100644 --- a/saml/signature/ContentReference.cpp +++ b/saml/signature/ContentReference.cpp @@ -1,67 +1,117 @@ -/* - * Copyright 2001-2006 Internet2 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * ContentReference.cpp - * - * SAML-specific signature reference profile - */ - -#include "internal.h" -#include "signature/ContentReference.h" -#include "signature/SignableObject.h" - -#include -#include -#include -#include - -using namespace opensaml; -using namespace std; - -class _addprefix : public binary_function { -public: - void operator()(DSIGTransformC14n* t, const string& s) const { - if (s.empty()) - t->addInclusiveNamespace("#default"); - else - t->addInclusiveNamespace(s.c_str()); - } -}; - -void ContentReference::createReferences(DSIGSignature* sig) -{ - const XMLCh* id=m_signableObject.getXMLID(); - if (!id || !*id) - throw xmlsignature::SignatureException("Cannot create Signature reference to SAML object without an identifier."); - - DSIGReference* ref=NULL; - XMLCh* buf=new XMLCh[XMLString::stringLen(id) + 2]; - buf[0]=chPound; - buf[1]=chNull; - XMLString::catString(buf,id); - try { - ref=sig->createReference(buf); - delete[] buf; - } - catch(...) { - delete[] buf; - throw; - } - ref->appendEnvelopedSignatureTransform(); - DSIGTransformC14n* c14n=ref->appendCanonicalizationTransform(CANON_C14NE_NOC); - for_each(m_prefixes.begin(), m_prefixes.end(), bind1st(_addprefix(),c14n)); -} +/* + * Copyright 2001-2010 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * ContentReference.cpp + * + * SAML-specific signature reference profile. + */ + +#include "internal.h" +#include "signature/ContentReference.h" +#include "signature/SignableObject.h" + +#include +#include +#include +#include +#include + +using namespace opensaml; +using namespace xmltooling; +using namespace std; + +void SignableObject::declareNonVisibleNamespaces() const +{ + ContentReference* cr = getSignature() ? dynamic_cast(getSignature()->getContentReference()) : nullptr; + + // Compute inclusive prefix set. + map decls; + XMLHelper::getNonVisiblyUsedPrefixes(*this, decls); + + for (map::const_iterator decl = decls.begin(); decl != decls.end(); ++decl) { + + // Pin it to the object root. An existing copy of the prefix on the root will take precedence. + addNamespace(Namespace(decl->second.c_str(), decl->first.c_str(), true, Namespace::NonVisiblyUsed)); + + // Add to content reference, if any. + if (cr) + cr->addInclusivePrefix(decl->first.c_str()); + } +} + +ContentReference::ContentReference(const SignableObject& signableObject) + : m_signableObject(signableObject), m_digest(nullptr), m_c14n(nullptr) +{ +} + +ContentReference::~ContentReference() +{ +} + +void ContentReference::createReferences(DSIGSignature* sig) +{ + DSIGReference* ref = nullptr; + const XMLCh* id=m_signableObject.getXMLID(); + if (!id || !*id) + ref=sig->createReference(&chNull, m_digest ? m_digest : DSIGConstants::s_unicodeStrURISHA1); // whole doc reference + else { + XMLCh* buf=new XMLCh[XMLString::stringLen(id) + 2]; + buf[0]=chPound; + buf[1]=chNull; + XMLString::catString(buf,id); + try { + ref=sig->createReference(buf, m_digest ? m_digest : DSIGConstants::s_unicodeStrURISHA1); + delete[] buf; + } + catch(...) { + delete[] buf; + throw; + } + } + + ref->appendEnvelopedSignatureTransform(); + DSIGTransformC14n* c14n=ref->appendCanonicalizationTransform(m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC); + + if (!m_c14n || m_c14n == DSIGConstants::s_unicodeStrURIEXC_C14N_NOC || m_c14n == DSIGConstants::s_unicodeStrURIEXC_C14N_COM) { + // Build up the string of prefixes. + xstring prefixes; + static const XMLCh _default[] = { chPound, chLatin_d, chLatin_e, chLatin_f, chLatin_a, chLatin_u, chLatin_l, chLatin_t, chNull }; + for (set::const_iterator p = m_prefixes.begin(); p != m_prefixes.end(); ++p) { + prefixes += (p->empty() ? _default : p->c_str()); + prefixes += chSpace; + } + if (!prefixes.empty()) { + prefixes.erase(prefixes.begin() + prefixes.size() - 1); + c14n->setInclusiveNamespaces(const_cast(prefixes.c_str())); + } + } +} + +void ContentReference::addInclusivePrefix(const XMLCh* prefix) +{ + m_prefixes.insert(prefix ? prefix : &chNull); +} + +void ContentReference::setDigestAlgorithm(const XMLCh* digest) +{ + m_digest = digest; +} + +void ContentReference::setCanonicalizationMethod(const XMLCh* c14n) +{ + m_c14n = c14n; +}