Boost related changes
[shibboleth/cpp-opensaml.git] / saml / signature / ContentReference.cpp
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * ContentReference.cpp
23  * 
24  * SAML-specific signature reference profile.
25  */
26  
27 #include "internal.h"
28 #include "signature/ContentReference.h"
29 #include "signature/SignableObject.h"
30
31 #include <xmltooling/signature/Signature.h>
32 #include <xercesc/util/XMLUniDefs.hpp>
33 #include <xsec/dsig/DSIGReference.hpp>
34 #include <xsec/dsig/DSIGSignature.hpp>
35 #include <xsec/dsig/DSIGTransformC14n.hpp>
36
37 using namespace opensaml;
38 using namespace xmltooling;
39 using namespace std;
40
41 void SignableObject::declareNonVisibleNamespaces() const
42 {
43     ContentReference* cr = getSignature() ? dynamic_cast<ContentReference*>(getSignature()->getContentReference()) : nullptr;
44
45     // Compute inclusive prefix set.
46     map<xstring,xstring> decls;
47     XMLHelper::getNonVisiblyUsedPrefixes(*this, decls);
48
49     for (map<xstring,xstring>::const_iterator decl = decls.begin(); decl != decls.end(); ++decl) {
50
51         // Pin it to the object root. An existing copy of the prefix on the root will take precedence.
52         addNamespace(Namespace(decl->second.c_str(), decl->first.c_str(), true, Namespace::NonVisiblyUsed));
53
54         // Add to content reference, if any.
55         if (cr)
56             cr->addInclusivePrefix(decl->first.c_str());
57     }
58 }
59
60 ContentReference::ContentReference(const SignableObject& signableObject)
61     : m_signableObject(signableObject), m_digest(nullptr), m_c14n(nullptr)
62 {
63 }
64
65 ContentReference::~ContentReference()
66 {
67 }
68
69 void ContentReference::createReferences(DSIGSignature* sig)
70 {
71     DSIGReference* ref = nullptr;
72     sig->setIdByAttributeName(false);
73     const XMLCh* id=m_signableObject.getXMLID();
74     if (!id || !*id)
75         ref=sig->createReference(&chNull, m_digest ? m_digest : DSIGConstants::s_unicodeStrURISHA1);  // whole doc reference
76     else {
77         XMLCh* buf=new XMLCh[XMLString::stringLen(id) + 2];
78         auto_arrayptr<XMLCh> bufjanitor(buf);
79         buf[0]=chPound;
80         buf[1]=chNull;
81         XMLString::catString(buf,id);
82         ref=sig->createReference(buf, m_digest ? m_digest : DSIGConstants::s_unicodeStrURISHA1);
83     }
84     
85     ref->appendEnvelopedSignatureTransform();
86     DSIGTransformC14n* c14n=ref->appendCanonicalizationTransform(m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC);
87
88     if (!m_c14n || m_c14n == DSIGConstants::s_unicodeStrURIEXC_C14N_NOC || m_c14n == DSIGConstants::s_unicodeStrURIEXC_C14N_COM) {
89         // Build up the string of prefixes.
90         xstring prefixes;
91         static const XMLCh _default[] = { chPound, chLatin_d, chLatin_e, chLatin_f, chLatin_a, chLatin_u, chLatin_l, chLatin_t, chNull };
92         for (set<xstring>::const_iterator p = m_prefixes.begin(); p != m_prefixes.end(); ++p) {
93             prefixes += (p->empty() ? _default : p->c_str());
94             prefixes += chSpace;
95         }
96         if (!prefixes.empty()) {
97             prefixes.erase(prefixes.begin() + prefixes.size() - 1);
98             c14n->setInclusiveNamespaces(const_cast<XMLCh*>(prefixes.c_str())); // the cast is for compatibility with old xmlsec
99         }
100     }
101 }
102
103 void ContentReference::addInclusivePrefix(const XMLCh* prefix)
104 {
105     m_prefixes.insert(prefix ? prefix : &chNull);
106 }
107
108 void ContentReference::setDigestAlgorithm(const XMLCh* digest)
109 {
110     m_digest = digest;
111 }
112
113 void ContentReference::setCanonicalizationMethod(const XMLCh* c14n)
114 {
115     m_c14n = c14n;
116 }