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