cb07142831e90e44e00664ca95fdbee3b8b6f823
[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/SigningContext.h>\r
20 #include <saml/signature/VerifyingContext.h>\r
21 \r
22 using namespace opensaml::saml1;\r
23 \r
24 #include <fstream>\r
25 #include <openssl/pem.h>\r
26 #include <xercesc/util/XMLUniDefs.hpp>\r
27 #include <xsec/enc/XSECKeyInfoResolverDefault.hpp>\r
28 #include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>\r
29 #include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>\r
30 #include <xmltooling/signature/Signature.h>\r
31 \r
32 class TestContext : public virtual CredentialResolver, public SigningContext, public VerifyingContext\r
33 {\r
34     vector<XSECCryptoX509*> m_certs;\r
35     OpenSSLCryptoKeyRSA* m_key;\r
36 public:\r
37     TestContext(const XMLCh* uri) : VerifyingContext(uri), SigningContext(uri,*this), m_key(NULL) {\r
38         string keypath=data_path + "key.pem";\r
39         BIO* in=BIO_new(BIO_s_file_internal());\r
40         if (in && BIO_read_filename(in,keypath.c_str())>0) {\r
41             EVP_PKEY* pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);\r
42             if (pkey) {\r
43                 m_key=new OpenSSLCryptoKeyRSA(pkey);\r
44                 EVP_PKEY_free(pkey);\r
45             }\r
46         }\r
47         if (in) BIO_free(in);\r
48         TS_ASSERT(m_key!=NULL);\r
49 \r
50         string certpath=data_path + "cert.pem";\r
51         in=BIO_new(BIO_s_file_internal());\r
52         if (in && BIO_read_filename(in,certpath.c_str())>0) {\r
53             X509* x=NULL;\r
54             while (x=PEM_read_bio_X509(in,NULL,NULL,NULL)) {\r
55                 m_certs.push_back(new OpenSSLCryptoX509(x));\r
56                 X509_free(x);\r
57             }\r
58         }\r
59         if (in) BIO_free(in);\r
60         TS_ASSERT(m_certs.size()>0);\r
61     }\r
62     \r
63     virtual ~TestContext() {\r
64         delete m_key;\r
65         for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());\r
66     }\r
67     \r
68     void verifySignature(DSIGSignature* sig) const {\r
69         VerifyingContext::verifySignature(sig);\r
70         sig->setSigningKey(NULL);\r
71         XSECKeyInfoResolverDefault resolver;\r
72         sig->setKeyInfoResolver(&resolver);\r
73         sig->verify();\r
74     }\r
75 \r
76     xmlsignature::KeyInfo* getKeyInfo() { return NULL; }\r
77     const char* getId() const { return "test"; }\r
78     const vector<XSECCryptoX509*>* getX509Certificates() { return &m_certs; }\r
79     XSECCryptoKey* getPublicKey() { return m_key; }\r
80     XSECCryptoKey* getPrivateKey() { return m_key; }\r
81     Lockable& lock() { return *this; }\r
82     void unlock() {}\r
83 };\r
84 \r
85 class SAML1AssertionTest : public CxxTest::TestSuite, public SAMLObjectBaseTestCase {\r
86 public:\r
87     void setUp() {\r
88         childElementsFile  = data_path + "signature/SAML1Assertion.xml";\r
89         SAMLObjectBaseTestCase::setUp();\r
90     }\r
91 \r
92     void tearDown() {\r
93         SAMLObjectBaseTestCase::tearDown();\r
94     }\r
95 \r
96     void testSignature() {\r
97         auto_ptr_XMLCh issuer("issuer");\r
98         auto_ptr_XMLCh issueInstant("1970-01-02T01:01:02.100Z");\r
99         auto_ptr_XMLCh id("ident");\r
100         auto_ptr_XMLCh method("method");\r
101         auto_ptr_XMLCh nameid("John Doe");\r
102         \r
103         NameIdentifier* n=NameIdentifierBuilder::buildNameIdentifier();\r
104         n->setName(nameid.get());        \r
105         Subject* subject=SubjectBuilder::buildSubject();\r
106         subject->setNameIdentifier(n);\r
107 \r
108         AuthenticationStatement* statement=AuthenticationStatementBuilder::buildAuthenticationStatement();\r
109         statement->setAuthenticationInstant(issueInstant.get());\r
110         statement->setAuthenticationMethod(method.get());\r
111         statement->setSubject(subject);\r
112         \r
113         auto_ptr<Assertion> assertion(AssertionBuilder::buildAssertion());\r
114         assertion->setAssertionID(id.get());\r
115         assertion->setIssueInstant(issueInstant.get());\r
116         assertion->setIssuer(issuer.get());\r
117         assertion->getAuthenticationStatements().push_back(statement);\r
118 \r
119         // Append a Signature.\r
120         xmlsignature::Signature* sig=xmlsignature::SignatureBuilder::newSignature();\r
121         assertion->setSignature(sig);\r
122         \r
123         // Signing context for the assertion.\r
124         TestContext tc(id.get());\r
125         MarshallingContext mctx(sig,&tc);\r
126         DOMElement* rootElement = assertion->marshall((DOMDocument*)NULL,&mctx);\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()->verify(tc);\r
138         }\r
139         catch (xmlsignature::SignatureException& e) {\r
140             TS_TRACE(e.what());\r
141             throw;\r
142         }\r
143     }\r
144 \r
145 };\r