Simplify storage context mgmt.
[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/KeyInfo.h>\r
21 #include <xmltooling/signature/SignatureValidator.h>\r
22 \r
23 #include <fstream>\r
24 #include <xercesc/util/XMLUniDefs.hpp>\r
25 #include <xsec/dsig/DSIGReference.hpp>\r
26 \r
27 class TestContext : public ContentReference\r
28 {\r
29     XMLCh* m_uri;\r
30     \r
31 public:\r
32     TestContext(const XMLCh* uri) {\r
33         m_uri=XMLString::replicate(uri);\r
34     }\r
35     \r
36     virtual ~TestContext() {\r
37         XMLString::release(&m_uri);\r
38     }\r
39 \r
40     void createReferences(DSIGSignature* sig) {\r
41         DSIGReference* ref=sig->createReference(m_uri);\r
42         ref->appendEnvelopedSignatureTransform();\r
43         ref->appendCanonicalizationTransform(CANON_C14NE_NOC);\r
44     }\r
45 };\r
46 \r
47 class TestValidator : public SignatureValidator\r
48 {\r
49     XMLCh* m_uri;\r
50     \r
51 public:\r
52     TestValidator(const XMLCh* uri) : SignatureValidator(XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER,NULL)) {\r
53         m_uri=XMLString::replicate(uri);\r
54     }\r
55     \r
56     virtual ~TestValidator() {\r
57         XMLString::release(&m_uri);\r
58     }\r
59 \r
60     void validate(const Signature* sigObj) const {\r
61         DSIGSignature* sig=sigObj->getXMLSignature();\r
62         if (!sig)\r
63             throw SignatureException("Only a marshalled Signature object can be verified.");\r
64         const XMLCh* uri=sig->getReferenceList()->item(0)->getURI();\r
65         TSM_ASSERT_SAME_DATA("Reference URI does not match.",uri,m_uri,XMLString::stringLen(uri));\r
66         SignatureValidator::validate(sigObj);\r
67     }\r
68 };\r
69 \r
70 class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {\r
71 public:\r
72     void operator()(X509Data* bag, XSECCryptoX509* cert) const {\r
73         safeBuffer& buf=cert->getDEREncodingSB();\r
74         X509Certificate* x=X509CertificateBuilder::buildX509Certificate();\r
75         x->setValue(buf.sbStrToXMLCh());\r
76         bag->getX509Certificates().push_back(x);\r
77     }\r
78 };\r
79 \r
80 class SignatureTest : public CxxTest::TestSuite {\r
81     CredentialResolver* m_resolver;\r
82 public:\r
83     void setUp() {\r
84         m_resolver=NULL;\r
85         QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
86         QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
87         XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());\r
88         XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());\r
89 \r
90         string config = data_path + "FilesystemCredentialResolver.xml";\r
91         ifstream in(config.c_str());\r
92         DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
93         XercesJanitor<DOMDocument> janitor(doc);\r
94         m_resolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(\r
95             FILESYSTEM_CREDENTIAL_RESOLVER,doc->getDocumentElement()\r
96             );\r
97     }\r
98 \r
99     void tearDown() {\r
100         QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
101         QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
102         XMLObjectBuilder::deregisterBuilder(qname);\r
103         XMLObjectBuilder::deregisterBuilder(qtype);\r
104         delete m_resolver;\r
105     }\r
106 \r
107     void testSignature() {\r
108         QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
109         const SimpleXMLObjectBuilder* b=dynamic_cast<const SimpleXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(qname));\r
110         TS_ASSERT(b!=NULL);\r
111         \r
112         auto_ptr<SimpleXMLObject> sxObject(b->buildObject());\r
113         TS_ASSERT(sxObject.get()!=NULL);\r
114         VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
115         kids.push_back(b->buildObject());\r
116         kids.push_back(b->buildObject());\r
117         \r
118         // Test some collection stuff\r
119         auto_ptr_XMLCh foo("Foo");\r
120         auto_ptr_XMLCh bar("Bar");\r
121         kids.begin()->setId(foo.get());\r
122         kids[1]->setValue(bar.get());\r
123         \r
124         // Append a Signature.\r
125         Signature* sig=SignatureBuilder::buildSignature();\r
126         sxObject->setSignature(sig);\r
127         sig->setContentReference(new TestContext(&chNull));\r
128 \r
129         Locker locker(m_resolver);\r
130         sig->setSigningKey(m_resolver->getKey());\r
131         \r
132         // Build KeyInfo.\r
133         KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();\r
134         X509Data* x509Data=X509DataBuilder::buildX509Data();\r
135         keyInfo->getX509Datas().push_back(x509Data);\r
136         for_each(m_resolver->getCertificates().begin(),m_resolver->getCertificates().end(),bind1st(_addcert(),x509Data));\r
137         sig->setKeyInfo(keyInfo);\r
138         \r
139         DOMElement* rootElement = NULL;\r
140         try {\r
141             rootElement=sxObject->marshall((DOMDocument*)NULL);\r
142             sig->sign();\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