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