Completed 2.0 assertions schema classes.
[shibboleth/cpp-opensaml.git] / samltest / signature / SAML1RequestTest.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 "internal.h"\r
18 #include <saml/saml1/core/Protocols.h>\r
19 #include <saml/signature/SignatureProfileValidator.h>\r
20 #include <xmltooling/signature/SignatureValidator.h>\r
21 \r
22 \r
23 #include <fstream>\r
24 #include <openssl/pem.h>\r
25 #include <xercesc/util/XMLUniDefs.hpp>\r
26 #include <xsec/enc/XSECKeyInfoResolverDefault.hpp>\r
27 #include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>\r
28 #include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>\r
29 #include <xsec/enc/XSECCryptoException.hpp>\r
30 #include <xsec/framework/XSECException.hpp>\r
31 \r
32 using namespace opensaml::saml1p;\r
33 using namespace opensaml::saml1;\r
34 using namespace xmlsignature;\r
35 \r
36 class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {\r
37 public:\r
38     void operator()(X509Data* bag, XSECCryptoX509* cert) const {\r
39         safeBuffer& buf=cert->getDEREncodingSB();\r
40         X509Certificate* x=X509CertificateBuilder::buildX509Certificate();\r
41         x->setValue(buf.sbStrToXMLCh());\r
42         bag->getX509Certificates().push_back(x);\r
43     }\r
44 };\r
45 \r
46 class SAML1RequestTest : public CxxTest::TestSuite, public SAMLObjectBaseTestCase {\r
47     XSECCryptoKey* m_key;\r
48     vector<XSECCryptoX509*> m_certs;\r
49 public:\r
50     void setUp() {\r
51         childElementsFile  = data_path + "signature/SAML1Request.xml";\r
52         SAMLObjectBaseTestCase::setUp();\r
53         string keypath=data_path + "key.pem";\r
54         BIO* in=BIO_new(BIO_s_file_internal());\r
55         if (in && BIO_read_filename(in,keypath.c_str())>0) {\r
56             EVP_PKEY* pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);\r
57             if (pkey) {\r
58                 m_key=new OpenSSLCryptoKeyRSA(pkey);\r
59                 EVP_PKEY_free(pkey);\r
60             }\r
61         }\r
62         if (in) BIO_free(in);\r
63         TS_ASSERT(m_key!=NULL);\r
64 \r
65         string certpath=data_path + "cert.pem";\r
66         in=BIO_new(BIO_s_file_internal());\r
67         if (in && BIO_read_filename(in,certpath.c_str())>0) {\r
68             X509* x=NULL;\r
69             while (x=PEM_read_bio_X509(in,NULL,NULL,NULL)) {\r
70                 m_certs.push_back(new OpenSSLCryptoX509(x));\r
71                 X509_free(x);\r
72             }\r
73         }\r
74         if (in) BIO_free(in);\r
75         TS_ASSERT(m_certs.size()>0);\r
76     }\r
77 \r
78     void tearDown() {\r
79         SAMLObjectBaseTestCase::tearDown();\r
80         delete m_key;\r
81         for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());\r
82     }\r
83 \r
84     void testSignature() {\r
85         auto_ptr_XMLCh issueInstant("1970-01-02T01:01:02.100Z");\r
86         auto_ptr_XMLCh id("ident");\r
87         auto_ptr_XMLCh method("method");\r
88         auto_ptr_XMLCh nameid("John Doe");\r
89         \r
90         NameIdentifier* n=NameIdentifierBuilder::buildNameIdentifier();\r
91         n->setName(nameid.get());        \r
92         Subject* subject=SubjectBuilder::buildSubject();\r
93         subject->setNameIdentifier(n);\r
94 \r
95         AuthenticationQuery* query=AuthenticationQueryBuilder::buildAuthenticationQuery();\r
96         query->setAuthenticationMethod(method.get());\r
97         query->setSubject(subject);\r
98         \r
99         auto_ptr<Request> request(RequestBuilder::buildRequest());\r
100         request->setRequestID(id.get());\r
101         request->setIssueInstant(issueInstant.get());\r
102         request->setAuthenticationQuery(query);\r
103 \r
104         // Append a Signature.\r
105         Signature* sig=SignatureBuilder::buildSignature();\r
106         request->setSignature(sig);\r
107         sig->setSigningKey(m_key->clone());\r
108 \r
109         // Build KeyInfo.\r
110         KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();\r
111         X509Data* x509Data=X509DataBuilder::buildX509Data();\r
112         keyInfo->getX509Datas().push_back(x509Data);\r
113         for_each(m_certs.begin(),m_certs.end(),bind1st(_addcert(),x509Data));\r
114         sig->setKeyInfo(keyInfo);\r
115 \r
116         // Sign while marshalling.\r
117         vector<Signature*> sigs(1,sig);\r
118         DOMElement* rootElement = NULL;\r
119         try {\r
120             rootElement=request->marshall((DOMDocument*)NULL,&sigs);\r
121         }\r
122         catch (XMLToolingException& e) {\r
123             TS_TRACE(e.what());\r
124             throw;\r
125         }\r
126         \r
127         string buf;\r
128         XMLHelper::serialize(rootElement, buf);\r
129         istringstream in(buf);\r
130         DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
131         const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
132 \r
133         assertEquals(expectedChildElementsDOM, b->buildFromDocument(doc));\r
134         \r
135         try {\r
136             request->getSignature()->registerValidator(new SignatureProfileValidator());\r
137             request->getSignature()->registerValidator(new SignatureValidator(m_key->clone()));\r
138             request->getSignature()->validate(true);\r
139         }\r
140         catch (XMLToolingException& e) {\r
141             TS_TRACE(e.what());\r
142             throw;\r
143         }\r
144     }\r
145 \r
146 };\r