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