m_pos_Signature=m_children.begin();
}
protected:
- AbstractRequestImpl() {}
+ AbstractRequestImpl() {
+ init();
+ }
public:
virtual ~AbstractRequestImpl() {
XMLString::release(&m_RequestID);
m_pos_Signature=m_children.begin();
}
protected:
- AbstractResponseImpl() {}
+ AbstractResponseImpl() {
+ init();
+ }
public:
virtual ~AbstractResponseImpl() {
XMLString::release(&m_ResponseID);
samltest_h = \
samltest.h \
+ saml/signature/SAML1AssertionTest.h \
+ saml/signature/SAML1RequestTest.h \
+ saml/signature/SAML1ResponseTest.h \
saml1/core/impl/ActionTest.h \
saml1/core/impl/AdviceTest.h \
saml1/core/impl/AssertionIDReferenceTest.h \
--- /dev/null
+<samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" IssueInstant="1970-01-02T01:01:02.100Z"
+MajorVersion="1" MinorVersion="1" RequestID="ident"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+<ds:SignedInfo>
+<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+<ds:Reference URI="#ident">
+<ds:Transforms>
+<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+</ds:Transforms>
+<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+<ds:DigestValue>pqhIt8nUldh3KVL6IEewRxKXYhM=</ds:DigestValue>
+</ds:Reference>
+</ds:SignedInfo>
+<ds:SignatureValue>UE5p832pLFYvMloRofN3y0rrFY7B8zOcF7+CHYyxFn6pqgPeEYGqkbUWlV15/tJ5
+wXJ3LiLQroYQI3XHPvKRSV4OtF9ZFm4QDK7RNd6gnUmHed6Zje//e6z2ekA0UzTl
+IeWCuD84mWemMJzRAhSFKcnqJDBHA61Krvg1kf/2c2E=</ds:SignatureValue>
+<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICjzCCAfigAwIBAgIJAKk8t1hYcMkhMA0GCSqGSIb3DQEBBAUAMDoxCzAJBgNV
+BAYTAlVTMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDnNwLmV4YW1wbGUu
+b3JnMB4XDTA1MDYyMDE1NDgzNFoXDTMyMTEwNTE1NDgzNFowOjELMAkGA1UEBhMC
+VVMxEjAQBgNVBAoTCUludGVybmV0MjEXMBUGA1UEAxMOc3AuZXhhbXBsZS5vcmcw
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANlZ1L1mKzYbUVKiMQLhZlfGDyYa
+/jjCiaXP0WhLNgvJpOTeajvsrApYNnFX5MLNzuC3NeQIjXUNLN2Yo2MCSthBIOL5
+qE5dka4z9W9zytoflW1LmJ8vXpx8Ay/meG4z//J5iCpYVEquA0xl28HUIlownZUF
+7w7bx0cF/02qrR23AgMBAAGjgZwwgZkwHQYDVR0OBBYEFJZiO1qsyAyc3HwMlL9p
+JpN6fbGwMGoGA1UdIwRjMGGAFJZiO1qsyAyc3HwMlL9pJpN6fbGwoT6kPDA6MQsw
+CQYDVQQGEwJVUzESMBAGA1UEChMJSW50ZXJuZXQyMRcwFQYDVQQDEw5zcC5leGFt
+cGxlLm9yZ4IJAKk8t1hYcMkhMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQAD
+gYEAMFq/UeSQyngE0GpZueyD2UW0M358uhseYOgGEIfm+qXIFQF6MYwNoX7WFzhC
+LJZ2E6mEvZZFHCHUtl7mGDvsRwgZ85YCtRbvleEpqfgNQToto9pLYe+X6vvH9Z6p
+gmYsTmak+kxO93JprrOd9xp8aZPMEprL7VCdrhbZEfyYER0=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><samlp:AuthenticationQuery AuthenticationMethod="method"><saml:Subject xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"><saml:NameIdentifier>John Doe</saml:NameIdentifier></saml:Subject></samlp:AuthenticationQuery></samlp:Request>
--- /dev/null
+<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" IssueInstant="1970-01-02T01:01:02.100Z" MajorVersion="1" MinorVersion="1" ResponseID="rident"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+<ds:SignedInfo>
+<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+<ds:Reference URI="#rident">
+<ds:Transforms>
+<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+</ds:Transforms>
+<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+<ds:DigestValue>WjLtIcoArwwdHVOks5QnbnFuE9g=</ds:DigestValue>
+</ds:Reference>
+</ds:SignedInfo>
+<ds:SignatureValue>cwC985/W+J8HrkDgMK1fYPfRP7e6aAAKJM/8rTWbOnI6feF8jrsQhSQ9qBon5o46
+4eHMDYAcH4xd9rGPeYib4jjH2hAPAF0rqLX1FWNTZgS+lJQFhhj5Sys0Ja6C0wsx
+0CoEWraR/IiDpRwnz9gGj2jGnfokfBdsLiomuxC2ZNY=</ds:SignatureValue>
+<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICjzCCAfigAwIBAgIJAKk8t1hYcMkhMA0GCSqGSIb3DQEBBAUAMDoxCzAJBgNV
+BAYTAlVTMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDnNwLmV4YW1wbGUu
+b3JnMB4XDTA1MDYyMDE1NDgzNFoXDTMyMTEwNTE1NDgzNFowOjELMAkGA1UEBhMC
+VVMxEjAQBgNVBAoTCUludGVybmV0MjEXMBUGA1UEAxMOc3AuZXhhbXBsZS5vcmcw
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANlZ1L1mKzYbUVKiMQLhZlfGDyYa
+/jjCiaXP0WhLNgvJpOTeajvsrApYNnFX5MLNzuC3NeQIjXUNLN2Yo2MCSthBIOL5
+qE5dka4z9W9zytoflW1LmJ8vXpx8Ay/meG4z//J5iCpYVEquA0xl28HUIlownZUF
+7w7bx0cF/02qrR23AgMBAAGjgZwwgZkwHQYDVR0OBBYEFJZiO1qsyAyc3HwMlL9p
+JpN6fbGwMGoGA1UdIwRjMGGAFJZiO1qsyAyc3HwMlL9pJpN6fbGwoT6kPDA6MQsw
+CQYDVQQGEwJVUzESMBAGA1UEChMJSW50ZXJuZXQyMRcwFQYDVQQDEw5zcC5leGFt
+cGxlLm9yZ4IJAKk8t1hYcMkhMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQAD
+gYEAMFq/UeSQyngE0GpZueyD2UW0M358uhseYOgGEIfm+qXIFQF6MYwNoX7WFzhC
+LJZ2E6mEvZZFHCHUtl7mGDvsRwgZ85YCtRbvleEpqfgNQToto9pLYe+X6vvH9Z6p
+gmYsTmak+kxO93JprrOd9xp8aZPMEprL7VCdrhbZEfyYER0=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><samlp:Status><samlp:StatusCode
+Value="samlp:Success"/></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" AssertionID="aident"
+IssueInstant="1970-01-02T01:01:02.100Z" Issuer="issuer" MajorVersion="1" MinorVersion="1"><saml:AuthenticationStatement
+AuthenticationInstant="1970-01-02T01:01:02.100Z"
+AuthenticationMethod="method"><saml:Subject><saml:NameIdentifier>John Doe</saml:NameIdentifier></saml:Subject></saml:AuthenticationStatement><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+<ds:SignedInfo>
+<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
+<ds:Reference URI="#aident">
+<ds:Transforms>
+<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
+<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
+</ds:Transforms>
+<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
+<ds:DigestValue>/owFROXYYru5+/j0TpHEz+hjXqY=</ds:DigestValue>
+</ds:Reference>
+</ds:SignedInfo>
+<ds:SignatureValue>d4SsRgDSjboTRA2YUD68TPp+17AqRmxbY/LrWJhueIC/JY+Ct7+Fd6bugUXliIeD
+NVRDACsEB7PqYWZ99+Ecf8XAmQYCw5elj8mWxPp0o+UVHtBZOR2bC+/YjNitSM+x
+G/F3JgZqfunUcg7mcj6WEAUt4pjKhjaTY8Z7QJltdKc=</ds:SignatureValue>
+<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICjzCCAfigAwIBAgIJAKk8t1hYcMkhMA0GCSqGSIb3DQEBBAUAMDoxCzAJBgNV
+BAYTAlVTMRIwEAYDVQQKEwlJbnRlcm5ldDIxFzAVBgNVBAMTDnNwLmV4YW1wbGUu
+b3JnMB4XDTA1MDYyMDE1NDgzNFoXDTMyMTEwNTE1NDgzNFowOjELMAkGA1UEBhMC
+VVMxEjAQBgNVBAoTCUludGVybmV0MjEXMBUGA1UEAxMOc3AuZXhhbXBsZS5vcmcw
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANlZ1L1mKzYbUVKiMQLhZlfGDyYa
+/jjCiaXP0WhLNgvJpOTeajvsrApYNnFX5MLNzuC3NeQIjXUNLN2Yo2MCSthBIOL5
+qE5dka4z9W9zytoflW1LmJ8vXpx8Ay/meG4z//J5iCpYVEquA0xl28HUIlownZUF
+7w7bx0cF/02qrR23AgMBAAGjgZwwgZkwHQYDVR0OBBYEFJZiO1qsyAyc3HwMlL9p
+JpN6fbGwMGoGA1UdIwRjMGGAFJZiO1qsyAyc3HwMlL9pJpN6fbGwoT6kPDA6MQsw
+CQYDVQQGEwJVUzESMBAGA1UEChMJSW50ZXJuZXQyMRcwFQYDVQQDEw5zcC5leGFt
+cGxlLm9yZ4IJAKk8t1hYcMkhMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQAD
+gYEAMFq/UeSQyngE0GpZueyD2UW0M358uhseYOgGEIfm+qXIFQF6MYwNoX7WFzhC
+LJZ2E6mEvZZFHCHUtl7mGDvsRwgZ85YCtRbvleEpqfgNQToto9pLYe+X6vvH9Z6p
+gmYsTmak+kxO93JprrOd9xp8aZPMEprL7VCdrhbZEfyYER0=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature></saml:Assertion></samlp:Response>
RelativePath=".\signature\SAML1AssertionTest.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\signature\SAML1RequestTest.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\signature\SAML1ResponseTest.cpp"\r
+ >\r
+ </File>\r
</Filter>\r
</Filter>\r
<Filter\r
>\r
<Tool\r
Name="VCCustomBuildTool"\r
+ CommandLine="\perl\bin\perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o "$(InputDir)$(InputName)".cpp "$(InputPath)"
"\r
+ Outputs=""$(InputDir)$(InputName)".cpp"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ CommandLine="\perl\bin\perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o "$(InputDir)$(InputName)".cpp "$(InputPath)"
"\r
+ Outputs=""$(InputDir)$(InputName)".cpp"\r
+ />\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath=".\signature\SAML1RequestTest.h"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ CommandLine="\perl\bin\perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o "$(InputDir)$(InputName)".cpp "$(InputPath)""\r
+ Outputs=""$(InputDir)$(InputName)".cpp"\r
+ />\r
+ </FileConfiguration>\r
+ <FileConfiguration\r
+ Name="Release|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ CommandLine="\perl\bin\perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o "$(InputDir)$(InputName)".cpp "$(InputPath)""\r
+ Outputs=""$(InputDir)$(InputName)".cpp"\r
+ />\r
+ </FileConfiguration>\r
+ </File>\r
+ <File\r
+ RelativePath=".\signature\SAML1ResponseTest.h"\r
+ >\r
+ <FileConfiguration\r
+ Name="Debug|Win32"\r
+ >\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
CommandLine="\perl\bin\perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o "$(InputDir)$(InputName)".cpp "$(InputPath)""\r
Outputs=""$(InputDir)$(InputName)".cpp"\r
/>\r
--- /dev/null
+/*\r
+ * Copyright 2001-2005 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "internal.h"\r
+#include <saml/saml1/core/Protocols.h>\r
+#include <saml/signature/SignatureProfileValidator.h>\r
+\r
+#include <xmltooling/signature/Signature.h>\r
+\r
+#include <fstream>\r
+#include <openssl/pem.h>\r
+#include <xercesc/util/XMLUniDefs.hpp>\r
+#include <xsec/enc/XSECKeyInfoResolverDefault.hpp>\r
+#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>\r
+#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>\r
+#include <xsec/enc/XSECCryptoException.hpp>\r
+#include <xsec/framework/XSECException.hpp>\r
+\r
+using namespace opensaml::saml1;\r
+using namespace xmlsignature;\r
+\r
+class TestValidator : public Validator\r
+{\r
+public:\r
+ TestValidator() {}\r
+ virtual ~TestValidator() {}\r
+\r
+ Validator* clone() const {\r
+ return new TestValidator();\r
+ }\r
+\r
+ void validate(const XMLObject* xmlObject) const {\r
+ DSIGSignature* sig=dynamic_cast<const Signature*>(xmlObject)->getXMLSignature();\r
+ if (!sig)\r
+ throw SignatureException("Only a marshalled Signature object can be verified.");\r
+ XSECKeyInfoResolverDefault resolver;\r
+ sig->setKeyInfoResolver(&resolver); // It will clone the resolver for us.\r
+ try {\r
+ if (!sig->verify())\r
+ throw SignatureException("Signature did not verify.");\r
+ }\r
+ catch(XSECException& e) {\r
+ auto_ptr_char temp(e.getMsg());\r
+ throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + temp.get());\r
+ }\r
+ catch(XSECCryptoException& e) {\r
+ throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + e.getMsg());\r
+ }\r
+ }\r
+};\r
+\r
+class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {\r
+public:\r
+ void operator()(X509Data* bag, XSECCryptoX509* cert) const {\r
+ safeBuffer& buf=cert->getDEREncodingSB();\r
+ X509Certificate* x=X509CertificateBuilder::buildX509Certificate();\r
+ x->setValue(buf.sbStrToXMLCh());\r
+ bag->getX509Certificates().push_back(x);\r
+ }\r
+};\r
+\r
+class SAML1RequestTest : public CxxTest::TestSuite, public SAMLObjectBaseTestCase {\r
+ XSECCryptoKey* m_key;\r
+ vector<XSECCryptoX509*> m_certs;\r
+public:\r
+ void setUp() {\r
+ childElementsFile = data_path + "signature/SAML1Request.xml";\r
+ SAMLObjectBaseTestCase::setUp();\r
+ string keypath=data_path + "key.pem";\r
+ BIO* in=BIO_new(BIO_s_file_internal());\r
+ if (in && BIO_read_filename(in,keypath.c_str())>0) {\r
+ EVP_PKEY* pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);\r
+ if (pkey) {\r
+ m_key=new OpenSSLCryptoKeyRSA(pkey);\r
+ EVP_PKEY_free(pkey);\r
+ }\r
+ }\r
+ if (in) BIO_free(in);\r
+ TS_ASSERT(m_key!=NULL);\r
+\r
+ string certpath=data_path + "cert.pem";\r
+ in=BIO_new(BIO_s_file_internal());\r
+ if (in && BIO_read_filename(in,certpath.c_str())>0) {\r
+ X509* x=NULL;\r
+ while (x=PEM_read_bio_X509(in,NULL,NULL,NULL)) {\r
+ m_certs.push_back(new OpenSSLCryptoX509(x));\r
+ X509_free(x);\r
+ }\r
+ }\r
+ if (in) BIO_free(in);\r
+ TS_ASSERT(m_certs.size()>0);\r
+ }\r
+\r
+ void tearDown() {\r
+ SAMLObjectBaseTestCase::tearDown();\r
+ delete m_key;\r
+ for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());\r
+ }\r
+\r
+ void testSignature() {\r
+ auto_ptr_XMLCh issueInstant("1970-01-02T01:01:02.100Z");\r
+ auto_ptr_XMLCh id("ident");\r
+ auto_ptr_XMLCh method("method");\r
+ auto_ptr_XMLCh nameid("John Doe");\r
+ \r
+ NameIdentifier* n=NameIdentifierBuilder::buildNameIdentifier();\r
+ n->setName(nameid.get()); \r
+ Subject* subject=SubjectBuilder::buildSubject();\r
+ subject->setNameIdentifier(n);\r
+\r
+ AuthenticationQuery* query=AuthenticationQueryBuilder::buildAuthenticationQuery();\r
+ query->setAuthenticationMethod(method.get());\r
+ query->setSubject(subject);\r
+ \r
+ auto_ptr<Request> request(RequestBuilder::buildRequest());\r
+ request->setRequestID(id.get());\r
+ request->setIssueInstant(issueInstant.get());\r
+ request->setAuthenticationQuery(query);\r
+\r
+ // Append a Signature.\r
+ Signature* sig=SignatureBuilder::buildSignature();\r
+ request->setSignature(sig);\r
+ sig->setSigningKey(m_key->clone());\r
+\r
+ // Build KeyInfo.\r
+ KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();\r
+ X509Data* x509Data=X509DataBuilder::buildX509Data();\r
+ keyInfo->getX509Datas().push_back(x509Data);\r
+ for_each(m_certs.begin(),m_certs.end(),bind1st(_addcert(),x509Data));\r
+ sig->setKeyInfo(keyInfo);\r
+\r
+ // Sign while marshalling.\r
+ vector<Signature*> sigs(1,sig);\r
+ DOMElement* rootElement = NULL;\r
+ try {\r
+ rootElement=request->marshall((DOMDocument*)NULL,&sigs);\r
+ }\r
+ catch (XMLToolingException& e) {\r
+ TS_TRACE(e.what());\r
+ throw;\r
+ }\r
+ \r
+ string buf;\r
+ XMLHelper::serialize(rootElement, buf);\r
+ istringstream in(buf);\r
+ DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
+ const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
+\r
+ assertEquals(expectedChildElementsDOM, b->buildFromDocument(doc));\r
+ \r
+ try {\r
+ request->getSignature()->registerValidator(new SignatureProfileValidator());\r
+ request->getSignature()->registerValidator(new TestValidator());\r
+ request->getSignature()->validate(true);\r
+ }\r
+ catch (XMLToolingException& e) {\r
+ TS_TRACE(e.what());\r
+ throw;\r
+ }\r
+ }\r
+\r
+};\r
--- /dev/null
+/*\r
+ * Copyright 2001-2005 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "internal.h"\r
+#include <saml/saml1/core/Protocols.h>\r
+#include <saml/signature/SignatureProfileValidator.h>\r
+\r
+#include <xmltooling/signature/Signature.h>\r
+\r
+#include <fstream>\r
+#include <openssl/pem.h>\r
+#include <xercesc/util/XMLUniDefs.hpp>\r
+#include <xsec/enc/XSECKeyInfoResolverDefault.hpp>\r
+#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>\r
+#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>\r
+#include <xsec/enc/XSECCryptoException.hpp>\r
+#include <xsec/framework/XSECException.hpp>\r
+\r
+using namespace opensaml::saml1;\r
+using namespace xmlsignature;\r
+\r
+class TestValidator : public Validator\r
+{\r
+public:\r
+ TestValidator() {}\r
+ virtual ~TestValidator() {}\r
+\r
+ Validator* clone() const {\r
+ return new TestValidator();\r
+ }\r
+\r
+ void validate(const XMLObject* xmlObject) const {\r
+ DSIGSignature* sig=dynamic_cast<const Signature*>(xmlObject)->getXMLSignature();\r
+ if (!sig)\r
+ throw SignatureException("Only a marshalled Signature object can be verified.");\r
+ XSECKeyInfoResolverDefault resolver;\r
+ sig->setKeyInfoResolver(&resolver); // It will clone the resolver for us.\r
+ try {\r
+ if (!sig->verify())\r
+ throw SignatureException("Signature did not verify.");\r
+ }\r
+ catch(XSECException& e) {\r
+ auto_ptr_char temp(e.getMsg());\r
+ throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + temp.get());\r
+ }\r
+ catch(XSECCryptoException& e) {\r
+ throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + e.getMsg());\r
+ }\r
+ }\r
+};\r
+\r
+class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {\r
+public:\r
+ void operator()(X509Data* bag, XSECCryptoX509* cert) const {\r
+ safeBuffer& buf=cert->getDEREncodingSB();\r
+ X509Certificate* x=X509CertificateBuilder::buildX509Certificate();\r
+ x->setValue(buf.sbStrToXMLCh());\r
+ bag->getX509Certificates().push_back(x);\r
+ }\r
+};\r
+\r
+class SAML1ResponseTest : public CxxTest::TestSuite, public SAMLObjectBaseTestCase {\r
+ XSECCryptoKey* m_key;\r
+ vector<XSECCryptoX509*> m_certs;\r
+public:\r
+ void setUp() {\r
+ childElementsFile = data_path + "signature/SAML1Response.xml";\r
+ SAMLObjectBaseTestCase::setUp();\r
+ string keypath=data_path + "key.pem";\r
+ BIO* in=BIO_new(BIO_s_file_internal());\r
+ if (in && BIO_read_filename(in,keypath.c_str())>0) {\r
+ EVP_PKEY* pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);\r
+ if (pkey) {\r
+ m_key=new OpenSSLCryptoKeyRSA(pkey);\r
+ EVP_PKEY_free(pkey);\r
+ }\r
+ }\r
+ if (in) BIO_free(in);\r
+ TS_ASSERT(m_key!=NULL);\r
+\r
+ string certpath=data_path + "cert.pem";\r
+ in=BIO_new(BIO_s_file_internal());\r
+ if (in && BIO_read_filename(in,certpath.c_str())>0) {\r
+ X509* x=NULL;\r
+ while (x=PEM_read_bio_X509(in,NULL,NULL,NULL)) {\r
+ m_certs.push_back(new OpenSSLCryptoX509(x));\r
+ X509_free(x);\r
+ }\r
+ }\r
+ if (in) BIO_free(in);\r
+ TS_ASSERT(m_certs.size()>0);\r
+ }\r
+\r
+ void tearDown() {\r
+ SAMLObjectBaseTestCase::tearDown();\r
+ delete m_key;\r
+ for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());\r
+ }\r
+\r
+ void testSignature() {\r
+ auto_ptr_XMLCh issuer("issuer");\r
+ auto_ptr_XMLCh issueInstant("1970-01-02T01:01:02.100Z");\r
+ auto_ptr_XMLCh aid("aident");\r
+ auto_ptr_XMLCh rid("rident");\r
+ auto_ptr_XMLCh method("method");\r
+ auto_ptr_XMLCh nameid("John Doe");\r
+ \r
+ NameIdentifier* n=NameIdentifierBuilder::buildNameIdentifier();\r
+ n->setName(nameid.get()); \r
+ Subject* subject=SubjectBuilder::buildSubject();\r
+ subject->setNameIdentifier(n);\r
+\r
+ AuthenticationStatement* statement=AuthenticationStatementBuilder::buildAuthenticationStatement();\r
+ statement->setAuthenticationInstant(issueInstant.get());\r
+ statement->setAuthenticationMethod(method.get());\r
+ statement->setSubject(subject);\r
+ \r
+ Assertion* assertion=AssertionBuilder::buildAssertion();\r
+ assertion->setAssertionID(aid.get());\r
+ assertion->setIssueInstant(issueInstant.get());\r
+ assertion->setIssuer(issuer.get());\r
+ assertion->getAuthenticationStatements().push_back(statement);\r
+\r
+ // Append a Signature.\r
+ assertion->setSignature(SignatureBuilder::buildSignature());\r
+ assertion->getSignature()->setSigningKey(m_key->clone());\r
+\r
+ // Build KeyInfo.\r
+ KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();\r
+ X509Data* x509Data=X509DataBuilder::buildX509Data();\r
+ keyInfo->getX509Datas().push_back(x509Data);\r
+ for_each(m_certs.begin(),m_certs.end(),bind1st(_addcert(),x509Data));\r
+ assertion->getSignature()->setKeyInfo(keyInfo);\r
+\r
+ // Sign assertion while marshalling.\r
+ vector<Signature*> sigs(1,assertion->getSignature());\r
+ DOMElement* rootElement = NULL;\r
+ try {\r
+ rootElement=assertion->marshall((DOMDocument*)NULL,&sigs);\r
+ }\r
+ catch (XMLToolingException& e) {\r
+ TS_TRACE(e.what());\r
+ delete assertion;\r
+ throw;\r
+ }\r
+\r
+ StatusCode* sc=StatusCodeBuilder::buildStatusCode();\r
+ sc->setValue(&StatusCode::SUCCESS);\r
+ Status* status=StatusBuilder::buildStatus();\r
+ status->setStatusCode(sc);\r
+\r
+ auto_ptr<Response> response(ResponseBuilder::buildResponse());\r
+ response->setResponseID(rid.get());\r
+ response->setIssueInstant(issueInstant.get());\r
+ response->setStatus(status);\r
+ response->getAssertions().push_back(assertion);\r
+ response->setSignature(SignatureBuilder::buildSignature());\r
+ response->getSignature()->setSigningKey(m_key->clone());\r
+ response->getSignature()->setKeyInfo(keyInfo->cloneKeyInfo());\r
+\r
+ // Sign response while marshalling.\r
+ sigs.clear();\r
+ sigs.push_back(response->getSignature());\r
+ rootElement = NULL;\r
+ try {\r
+ rootElement=response->marshall((DOMDocument*)NULL,&sigs);\r
+ }\r
+ catch (XMLToolingException& e) {\r
+ TS_TRACE(e.what());\r
+ throw;\r
+ }\r
+\r
+ string buf;\r
+ XMLHelper::serialize(rootElement, buf);\r
+ istringstream in(buf);\r
+ DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
+ const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
+ \r
+ assertEquals(expectedChildElementsDOM, b->buildFromDocument(doc));\r
+ \r
+ try {\r
+ assertion->getSignature()->registerValidator(new SignatureProfileValidator());\r
+ assertion->getSignature()->registerValidator(new TestValidator());\r
+ assertion->getSignature()->validate(true);\r
+ response->getSignature()->registerValidator(new SignatureProfileValidator());\r
+ response->getSignature()->registerValidator(new TestValidator());\r
+ response->getSignature()->validate(true);\r
+ }\r
+ catch (XMLToolingException& e) {\r
+ TS_TRACE(e.what());\r
+ throw;\r
+ }\r
+ }\r
+\r
+};\r