Remove some tracing, fix string compares.
[shibboleth/cpp-xmltooling.git] / xmltoolingtest / SignatureTest.h
1 /*\r
2  *  Copyright 2001-2005 Internet2\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 #include "XMLObjectBaseTestCase.h"\r
18 \r
19 #include <xmltooling/signature/CredentialResolver.h>\r
20 #include <xmltooling/signature/SignatureValidator.h>\r
21 \r
22 #include <fstream>\r
23 #include <xercesc/util/XMLUniDefs.hpp>\r
24 #include <xsec/dsig/DSIGReference.hpp>\r
25 \r
26 class TestContext : public ContentReference\r
27 {\r
28     XMLCh* m_uri;\r
29     \r
30 public:\r
31     TestContext(const XMLCh* uri) {\r
32         m_uri=XMLString::replicate(uri);\r
33     }\r
34     \r
35     virtual ~TestContext() {\r
36         XMLString::release(&m_uri);\r
37     }\r
38 \r
39     void createReferences(DSIGSignature* sig) {\r
40         DSIGReference* ref=sig->createReference(m_uri);\r
41         ref->appendEnvelopedSignatureTransform();\r
42         ref->appendCanonicalizationTransform(CANON_C14NE_NOC);\r
43     }\r
44 };\r
45 \r
46 class TestValidator : public SignatureValidator\r
47 {\r
48     XMLCh* m_uri;\r
49     \r
50 public:\r
51     TestValidator(const XMLCh* uri) : SignatureValidator(XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER,NULL)) {\r
52         m_uri=XMLString::replicate(uri);\r
53     }\r
54     \r
55     virtual ~TestValidator() {\r
56         XMLString::release(&m_uri);\r
57     }\r
58 \r
59     void validate(const Signature* sigObj) const {\r
60         DSIGSignature* sig=sigObj->getXMLSignature();\r
61         if (!sig)\r
62             throw SignatureException("Only a marshalled Signature object can be verified.");\r
63         const XMLCh* uri=sig->getReferenceList()->item(0)->getURI();\r
64         TSM_ASSERT_SAME_DATA("Reference URI does not match.",uri,m_uri,XMLString::stringLen(uri));\r
65         SignatureValidator::validate(sigObj);\r
66     }\r
67 };\r
68 \r
69 class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {\r
70 public:\r
71     void operator()(X509Data* bag, XSECCryptoX509* cert) const {\r
72         safeBuffer& buf=cert->getDEREncodingSB();\r
73         X509Certificate* x=X509CertificateBuilder::buildX509Certificate();\r
74         x->setValue(buf.sbStrToXMLCh());\r
75         bag->getX509Certificates().push_back(x);\r
76     }\r
77 };\r
78 \r
79 class SignatureTest : public CxxTest::TestSuite {\r
80     CredentialResolver* m_resolver;\r
81 public:\r
82     void setUp() {\r
83         m_resolver=NULL;\r
84         QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
85         QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
86         XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());\r
87         XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());\r
88 \r
89         string config = data_path + "FilesystemCredentialResolver.xml";\r
90         ifstream in(config.c_str());\r
91         DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
92         XercesJanitor<DOMDocument> janitor(doc);\r
93         m_resolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(\r
94             FILESYSTEM_CREDENTIAL_RESOLVER,doc->getDocumentElement()\r
95             );\r
96     }\r
97 \r
98     void tearDown() {\r
99         QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
100         QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
101         XMLObjectBuilder::deregisterBuilder(qname);\r
102         XMLObjectBuilder::deregisterBuilder(qtype);\r
103         delete m_resolver;\r
104     }\r
105 \r
106     void testSignature() {\r
107         QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
108         const SimpleXMLObjectBuilder* b=dynamic_cast<const SimpleXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(qname));\r
109         TS_ASSERT(b!=NULL);\r
110         \r
111         auto_ptr<SimpleXMLObject> sxObject(b->buildObject());\r
112         TS_ASSERT(sxObject.get()!=NULL);\r
113         VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
114         kids.push_back(b->buildObject());\r
115         kids.push_back(b->buildObject());\r
116         \r
117         // Test some collection stuff\r
118         auto_ptr_XMLCh foo("Foo");\r
119         auto_ptr_XMLCh bar("Bar");\r
120         kids.begin()->setId(foo.get());\r
121         kids[1]->setValue(bar.get());\r
122         \r
123         // Append a Signature.\r
124         Signature* sig=SignatureBuilder::buildSignature();\r
125         sxObject->setSignature(sig);\r
126         sig->setContentReference(new TestContext(&chNull));\r
127 \r
128         Locker locker(m_resolver);\r
129         sig->setSigningKey(m_resolver->getKey());\r
130         \r
131         // Build KeyInfo.\r
132         KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();\r
133         X509Data* x509Data=X509DataBuilder::buildX509Data();\r
134         keyInfo->getX509Datas().push_back(x509Data);\r
135         for_each(m_resolver->getCertificates().begin(),m_resolver->getCertificates().end(),bind1st(_addcert(),x509Data));\r
136         sig->setKeyInfo(keyInfo);\r
137         \r
138         // Signing context for the whole document.\r
139         vector<Signature*> sigs(1,sig);\r
140         DOMElement* rootElement = NULL;\r
141         try {\r
142             rootElement=sxObject->marshall((DOMDocument*)NULL,&sigs);\r
143         }\r
144         catch (XMLToolingException& e) {\r
145             TS_TRACE(e.what());\r
146             throw;\r
147         }\r
148         \r
149         string buf;\r
150         XMLHelper::serialize(rootElement, buf);\r
151         //TS_TRACE(buf.c_str());\r
152 \r
153         istringstream in(buf);\r
154         DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
155         auto_ptr<SimpleXMLObject> sxObject2(dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc)));\r
156         TS_ASSERT(sxObject2.get()!=NULL);\r
157         TS_ASSERT(sxObject2->getSignature()!=NULL);\r
158         \r
159         try {\r
160             TestValidator tv(&chNull);\r
161             tv.validate(sxObject2->getSignature());\r
162         }\r
163         catch (XMLToolingException& e) {\r
164             TS_TRACE(e.what());\r
165             throw;\r
166         }\r
167     }\r
168 \r
169 };\r