Set fourth file version digit to signify rebuild.
[shibboleth/cpp-xmltooling.git] / xmltoolingtest / SignatureTest.h
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 #include "XMLObjectBaseTestCase.h"
22
23 #include <xmltooling/security/Credential.h>
24 #include <xmltooling/security/CredentialCriteria.h>
25 #include <xmltooling/security/CredentialResolver.h>
26 #include <xmltooling/signature/ContentReference.h>
27 #include <xmltooling/signature/KeyInfo.h>
28 #include <xmltooling/signature/SignatureValidator.h>
29
30 #include <fstream>
31 #include <xercesc/util/XMLUniDefs.hpp>
32 #include <xsec/dsig/DSIGReference.hpp>
33 #include <xsec/dsig/DSIGSignature.hpp>
34
35 class TestContext : public ContentReference
36 {
37     XMLCh* m_uri;
38     
39 public:
40     TestContext(const XMLCh* uri) {
41         m_uri=XMLString::replicate(uri);
42     }
43     
44     virtual ~TestContext() {
45         XMLString::release(&m_uri);
46     }
47
48     void createReferences(DSIGSignature* sig) {
49         DSIGReference* ref=sig->createReference(m_uri);
50         ref->appendEnvelopedSignatureTransform();
51         ref->appendCanonicalizationTransform(CANON_C14NE_NOC);
52     }
53 };
54
55 class TestValidator : public SignatureValidator
56 {
57     XMLCh* m_uri;
58     
59 public:
60     TestValidator(const XMLCh* uri, const Credential* credential) : SignatureValidator(credential) {
61         m_uri=XMLString::replicate(uri);
62     }
63     
64     virtual ~TestValidator() {
65         XMLString::release(&m_uri);
66     }
67
68     void validate(const Signature* sigObj) const {
69         DSIGSignature* sig=sigObj->getXMLSignature();
70         if (!sig)
71             throw SignatureException("Only a marshalled Signature object can be verified.");
72         const XMLCh* uri=sig->getReferenceList()->item(0)->getURI();
73         TSM_ASSERT_SAME_DATA("Reference URI does not match.",uri,m_uri,XMLString::stringLen(uri));
74         SignatureValidator::validate(sigObj);
75     }
76 };
77
78 class SignatureTest : public CxxTest::TestSuite {
79     CredentialResolver* m_resolver;
80 public:
81     void setUp() {
82         m_resolver=nullptr;
83         xmltooling::QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
84         xmltooling::QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
85         XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());
86         XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());
87
88         string config = data_path + "FilesystemCredentialResolver.xml";
89         ifstream in(config.c_str());
90         DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
91         XercesJanitor<DOMDocument> janitor(doc);
92         m_resolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(
93             CHAINING_CREDENTIAL_RESOLVER,doc->getDocumentElement()
94             );
95     }
96
97     void tearDown() {
98         xmltooling::QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
99         xmltooling::QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
100         XMLObjectBuilder::deregisterBuilder(qname);
101         XMLObjectBuilder::deregisterBuilder(qtype);
102         delete m_resolver;
103     }
104
105     void testSignature() {
106         xmltooling::QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
107         const SimpleXMLObjectBuilder* b=dynamic_cast<const SimpleXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(qname));
108         TS_ASSERT(b!=nullptr);
109         
110         auto_ptr<SimpleXMLObject> sxObject(dynamic_cast<SimpleXMLObject*>(b->buildObject()));
111         TS_ASSERT(sxObject.get()!=nullptr);
112         VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();
113         kids.push_back(dynamic_cast<SimpleXMLObject*>(b->buildObject()));
114         kids.push_back(dynamic_cast<SimpleXMLObject*>(b->buildObject()));
115         
116         // Test some collection stuff
117         auto_ptr_XMLCh foo("Foo");
118         auto_ptr_XMLCh bar("Bar");
119         kids.begin()->setId(foo.get());
120         kids[1]->setValue(bar.get());
121         
122         // Append a Signature.
123         Signature* sig=SignatureBuilder::buildSignature();
124         sxObject->setSignature(sig);
125         sig->setContentReference(new TestContext(&chNull));
126
127         CredentialCriteria cc;
128         cc.setUsage(Credential::SIGNING_CREDENTIAL);
129         Locker locker(m_resolver);
130         const Credential* cred = m_resolver->resolve(&cc);
131         TSM_ASSERT("Retrieved credential was null", cred!=nullptr);
132         
133         DOMElement* rootElement = nullptr;
134         try {
135             vector<Signature*> sigs(1,sig);
136             rootElement=sxObject->marshall((DOMDocument*)nullptr,&sigs,cred);
137         }
138         catch (XMLToolingException& e) {
139             TS_TRACE(e.what());
140             throw;
141         }
142         
143         string buf;
144         XMLHelper::serialize(rootElement, buf);
145         //TS_TRACE(buf.c_str());
146
147         istringstream in(buf);
148         DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
149         auto_ptr<SimpleXMLObject> sxObject2(dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc)));
150         TS_ASSERT(sxObject2.get()!=nullptr);
151         TS_ASSERT(sxObject2->getSignature()!=nullptr);
152         
153         try {
154             TestValidator tv(&chNull, cred);
155             tv.validate(sxObject2->getSignature());
156         }
157         catch (XMLToolingException& e) {
158             TS_TRACE(e.what());
159             throw;
160         }
161     }
162
163 };