saml1/core/Protocols.h
saml1bindinclude_HEADERS = \
- saml1/binding/SAML1ArtifactEncoder.h \
- saml1/binding/SAML1POSTEncoder.h \
saml1/binding/SAMLArtifactType0001.h \
- saml1/binding/SAMLArtifactType0002.h
+ saml1/binding/SAMLArtifactType0002.h \
+ saml1/binding/SAML1ArtifactEncoder.h \
+ saml1/binding/SAML1POSTEncoder.h
saml2coreinclude_HEADERS = \
saml2/core/Assertions.h \
saml2bindinclude_HEADERS = \
saml2/binding/SAML2Artifact.h \
- saml2/binding/SAML2ArtifactType0004.h
+ saml2/binding/SAML2ArtifactType0004.h \
+ saml1/binding/SAML2ArtifactEncoder.h \
+ saml1/binding/SAML2POSTEncoder.h
saml2mdinclude_HEADERS = \
saml2/metadata/AbstractMetadataProvider.h \
saml1/core/impl/AssertionsSchemaValidators.cpp \
saml1/core/impl/ProtocolsImpl.cpp \
saml1/core/impl/ProtocolsSchemaValidators.cpp \
- saml1/binding/impl/SAML1ArtifactEncoder.cpp \
- saml1/binding/impl/SAML1POSTEncoder.cpp \
saml1/binding/impl/SAMLArtifactType0001.cpp \
saml1/binding/impl/SAMLArtifactType0002.cpp \
+ saml1/binding/impl/SAML1ArtifactEncoder.cpp \
+ saml1/binding/impl/SAML1POSTEncoder.cpp \
saml2/core/impl/Assertions20Impl.cpp \
saml2/core/impl/Assertions20SchemaValidators.cpp \
saml2/core/impl/Protocols20Impl.cpp \
saml2/metadata/impl/WhitelistMetadataFilter.cpp \
saml2/binding/impl/SAML2Artifact.cpp \
saml2/binding/impl/SAML2ArtifactType0004.cpp \
+ saml2/binding/impl/SAML2ArtifactEncoder.cpp \
+ saml2/binding/impl/SAML2POSTEncoder.cpp \
encryption/EncryptedKeyResolver.cpp \
security/impl/TrustEngine.cpp \
security/impl/AbstractPKIXTrustEngine.cpp \
protected:\r
MessageEncoder() : m_urlEncoder(NULL), m_artifactGenerator(NULL) {}\r
\r
+ /**\r
+ * Helper function to build a new XML Signature with KeyInfo, based\r
+ * on the supplied CredentialResolver.\r
+ * \r
+ * @param credResolver CredentialResolver instance to supply signing material\r
+ * @param sigAlgorithm optional signature algorithm identifier\r
+ * @return a new Signature object\r
+ */\r
+ xmlsignature::Signature* buildSignature(\r
+ const xmlsignature::CredentialResolver* credResolver,\r
+ const XMLCh* sigAlgorithm=NULL\r
+ ) const;\r
+ \r
/** Pointer to a URLEncoder implementation. */\r
const URLEncoder* m_urlEncoder;\r
\r
\r
/** MessageEncoder for SAML 1.x Browser/POST "binding" (really part of profile) */\r
#define SAML1_POST_ENCODER "urn:oasis:names:tc:SAML:1.0:profiles:browser-post"\r
+ \r
+ /** MessageEncoder for SAML 2.0 HTTP-Artifact binding */\r
+ #define SAML2_ARTIFACT_ENCODER "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"\r
+\r
+ /** MessageEncoder for SAML 2.0 HTTP-POST binding */\r
+ #define SAML2_POST_ENCODER "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"\r
+\r
+ /** MessageEncoder for SAML 2.0 HTTP-Redirect binding */\r
+ #define SAML2_REDIRECT_ENCODER "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"\r
};\r
\r
#endif /* __saml_encoder_h__ */\r
#include "internal.h"
#include "binding/MessageEncoder.h"
+#include <xmltooling/signature/KeyInfo.h>
+#include <xmltooling/signature/Signature.h>
+
using namespace opensaml;
+using namespace xmlsignature;
using namespace xmltooling;
using namespace std;
SAML_DLLLOCAL PluginManager<MessageEncoder,const DOMElement*>::Factory SAML1ArtifactEncoderFactory;
SAML_DLLLOCAL PluginManager<MessageEncoder,const DOMElement*>::Factory SAML1POSTEncoderFactory;
};
+
+ namespace saml2p {
+ SAML_DLLLOCAL PluginManager<MessageEncoder,const DOMElement*>::Factory SAML2ArtifactEncoderFactory;
+ SAML_DLLLOCAL PluginManager<MessageEncoder,const DOMElement*>::Factory SAML2POSTEncoderFactory;
+ };
};
void SAML_API opensaml::registerMessageEncoders()
SAMLConfig& conf=SAMLConfig::getConfig();
conf.MessageEncoderManager.registerFactory(SAML1_ARTIFACT_ENCODER, saml1p::SAML1ArtifactEncoderFactory);
conf.MessageEncoderManager.registerFactory(SAML1_POST_ENCODER, saml1p::SAML1POSTEncoderFactory);
+ conf.MessageEncoderManager.registerFactory(SAML2_ARTIFACT_ENCODER, saml2p::SAML2ArtifactEncoderFactory);
+ conf.MessageEncoderManager.registerFactory(SAML2_POST_ENCODER, saml2p::SAML2POSTEncoderFactory);
+}
+
+namespace {
+ class SAML_DLLLOCAL _addcert : public binary_function<X509Data*,XSECCryptoX509*,void> {
+ public:
+ void operator()(X509Data* bag, XSECCryptoX509* cert) const {
+ safeBuffer& buf=cert->getDEREncodingSB();
+ X509Certificate* x=X509CertificateBuilder::buildX509Certificate();
+ x->setValue(buf.sbStrToXMLCh());
+ bag->getX509Certificates().push_back(x);
+ }
+ };
+};
+
+Signature* MessageEncoder::buildSignature(const CredentialResolver* credResolver, const XMLCh* sigAlgorithm) const
+{
+ // Build a Signature.
+ Signature* sig = SignatureBuilder::buildSignature();
+ if (sigAlgorithm)
+ sig->setSignatureAlgorithm(sigAlgorithm);
+ sig->setSigningKey(credResolver->getKey());
+
+ // Build KeyInfo.
+ const vector<XSECCryptoX509*>& certs = credResolver->getCertificates();
+ if (!certs.empty()) {
+ KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();
+ X509Data* x509Data=X509DataBuilder::buildX509Data();
+ keyInfo->getX509Datas().push_back(x509Data);
+ for_each(certs.begin(),certs.end(),bind1st(_addcert(),x509Data));
+ sig->setKeyInfo(keyInfo);
+ }
+
+ return sig;
}
</FileConfiguration>\r
</File>\r
<File\r
+ RelativePath=".\saml2\binding\impl\SAML2ArtifactEncoder.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\saml2\binding\impl\SAML2ArtifactType0004.cpp"\r
>\r
<FileConfiguration\r
/>\r
</FileConfiguration>\r
</File>\r
+ <File\r
+ RelativePath=".\saml2\binding\impl\SAML2POSTEncoder.cpp"\r
+ >\r
+ </File>\r
</Filter>\r
</Filter>\r
</Filter>\r
>\r
</File>\r
<File\r
+ RelativePath=".\saml2\binding\SAML2ArtifactEncoder.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\saml2\binding\SAML2ArtifactType0004.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\saml2\binding\SAML2POSTEncoder.h"\r
+ >\r
+ </File>\r
</Filter>\r
</Filter>\r
<Filter\r
/**
* SAML1POSTEncoder.cpp
*
- * SAML 1.x Artifact binding/profile message encoder
+ * SAML 1.x POST binding/profile message encoder
*/
#include "internal.h"
{
return new SAML1POSTEncoder(e);
}
-
- class SAML_DLLLOCAL _addcert : public binary_function<X509Data*,XSECCryptoX509*,void> {
- public:
- void operator()(X509Data* bag, XSECCryptoX509* cert) const {
- safeBuffer& buf=cert->getDEREncodingSB();
- X509Certificate* x=X509CertificateBuilder::buildX509Certificate();
- x->setValue(buf.sbStrToXMLCh());
- bag->getX509Certificates().push_back(x);
- }
- };
};
};
else {
log.debug("signing and marshalling the response");
- // Append a Signature.
- response->setSignature(SignatureBuilder::buildSignature());
- response->getSignature()->setSigningKey(credResolver->getKey());
-
- // Build KeyInfo.
- const vector<XSECCryptoX509*>& certs = credResolver->getCertificates();
- if (!certs.empty()) {
- KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();
- X509Data* x509Data=X509DataBuilder::buildX509Data();
- keyInfo->getX509Datas().push_back(x509Data);
- for_each(certs.begin(),certs.end(),bind1st(_addcert(),x509Data));
- response->getSignature()->setKeyInfo(keyInfo);
- }
+ // Build a Signature.
+ Signature* sig = buildSignature(credResolver, sigAlgorithm);
+ response->setSignature(sig);
// Sign response while marshalling.
- vector<Signature*> sigs(1,response->getSignature());
+ vector<Signature*> sigs(1,sig);
rootElement = response->marshall((DOMDocument*)NULL,&sigs);
}
}
--- /dev/null
+/*
+ * Copyright 2001-2006 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file saml/saml2/binding/SAML2ArtifactEncoder.h
+ *
+ * SAML 2.0 HTTP-Artifact binding message encoder
+ */
+
+#include <saml/binding/MessageEncoder.h>
+
+
+namespace opensaml {
+ namespace saml2p {
+
+ /**
+ * SAML 2.0 HTTP-Artifact binding message encoder
+ */
+ class SAML_API SAML2ArtifactEncoder : public MessageEncoder
+ {
+ public:
+ SAML2ArtifactEncoder(const DOMElement* e);
+ virtual ~SAML2ArtifactEncoder();
+
+ void encode(
+ std::map<std::string,std::string>& outputFields,
+ xmltooling::XMLObject* xmlObject,
+ const char* recipientID=NULL,
+ const char* relayState=NULL,
+ const xmlsignature::CredentialResolver* credResolver=NULL,
+ const XMLCh* sigAlgorithm=NULL
+ ) const;
+ };
+
+ };
+};
--- /dev/null
+/*
+ * Copyright 2001-2006 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file saml/saml2/binding/SAML2POSTEncoder.h
+ *
+ * SAML 2.0 HTTP-POST binding message encoder
+ */
+
+#include <saml/binding/MessageEncoder.h>
+
+
+namespace opensaml {
+ namespace saml2p {
+
+ /**
+ * SAML 2.0 HTTP-POST binding message encoder
+ */
+ class SAML_API SAML2POSTEncoder : public MessageEncoder
+ {
+ public:
+ SAML2POSTEncoder(const DOMElement* e);
+ virtual ~SAML2POSTEncoder();
+
+ void encode(
+ std::map<std::string,std::string>& outputFields,
+ xmltooling::XMLObject* xmlObject,
+ const char* recipientID=NULL,
+ const char* relayState=NULL,
+ const xmlsignature::CredentialResolver* credResolver=NULL,
+ const XMLCh* sigAlgorithm=NULL
+ ) const;
+ };
+
+ };
+};
--- /dev/null
+/*
+ * Copyright 2001-2006 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * SAML2ArtifactEncoder.cpp
+ *
+ * SAML 2.0 HTTP-Artifact binding message encoder
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "saml2/binding/SAML2Artifact.h"
+#include "saml2/binding/SAML2ArtifactEncoder.h"
+#include "saml2/core/Protocols.h"
+
+#include <log4cpp/Category.hh>
+#include <xmltooling/util/NDC.h>
+
+using namespace opensaml::saml2p;
+using namespace opensaml;
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace opensaml {
+ namespace saml2p {
+ MessageEncoder* SAML_DLLLOCAL SAML2ArtifactEncoderFactory(const DOMElement* const & e)
+ {
+ return new SAML2ArtifactEncoder(e);
+ }
+ };
+};
+
+SAML2ArtifactEncoder::SAML2ArtifactEncoder(const DOMElement* e) {}
+
+SAML2ArtifactEncoder::~SAML2ArtifactEncoder() {}
+
+void SAML2ArtifactEncoder::encode(
+ map<string,string>& outputFields,
+ XMLObject* xmlObject,
+ const char* recipientID,
+ const char* relayState,
+ const CredentialResolver* credResolver,
+ const XMLCh* sigAlgorithm
+ ) const
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("encode");
+#endif
+ Category& log = Category::getInstance(SAML_LOGCAT".MessageEncoder.SAML2Artifact");
+ log.debug("validating input");
+
+ outputFields.clear();
+ if (xmlObject->getParent())
+ throw BindingException("Cannot encode XML content with parent.");
+
+ StatusResponseType* response = NULL;
+ RequestAbstractType* request = dynamic_cast<RequestAbstractType*>(xmlObject);
+ if (!request)
+ response = dynamic_cast<StatusResponseType*>(xmlObject);
+ if (!response)
+ throw BindingException("XML content for SAML 2.0 HTTP-Artifact Encoder must be a SAML 2.0 protocol message.");
+
+ ArtifactMap* mapper = SAMLConfig::getConfig().getArtifactMap();
+ if (!mapper)
+ throw BindingException("SAML 2.0 HTTP-Artifact Encoder requires ArtifactMap be set in configuration.");
+
+ // Obtain a fresh artifact.
+ if (!m_artifactGenerator)
+ throw BindingException("SAML 2.0 HTTP-Artifact Encoder requires an ArtifactGenerator instance.");
+ log.debug("obtaining new artifact for relying party (%s)", recipientID ? recipientID : "unknown");
+ auto_ptr<SAMLArtifact> artifact(m_artifactGenerator->generateSAML2Artifact(recipientID));
+
+ if (credResolver) {
+ // Signature based on native XML signing.
+ if (request ? request->getSignature() : response->getSignature()) {
+ log.debug("message already signed, skipping signature operation");
+ }
+ else {
+ log.debug("signing the message");
+
+ // Build a Signature.
+ Signature* sig = buildSignature(credResolver, sigAlgorithm);
+
+ // Append Signature.
+ request ? request->setSignature(sig) : response->setSignature(sig);
+
+ // Sign response while marshalling.
+ vector<Signature*> sigs(1,sig);
+ xmlObject->marshall((DOMDocument*)NULL,&sigs);
+ }
+ }
+
+ // Pass back output fields.
+ outputFields["SAMLart"] = artifact->encode();
+ if (relayState)
+ outputFields["RelayState"] = relayState;
+
+ // Store the message. Last step in storage will be to delete the XML.
+ log.debug("storing artifact and content in map");
+ mapper->storeContent(xmlObject, artifact.get(), recipientID);
+
+ log.debug("message encoded");
+}
--- /dev/null
+/*
+ * Copyright 2001-2006 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * SAML2POSTEncoder.cpp
+ *
+ * SAML 2.0 HTTP-POST binding message encoder
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "saml2/binding/SAML2POSTEncoder.h"
+#include "saml2/core/Protocols.h"
+
+#include <log4cpp/Category.hh>
+#include <xercesc/util/Base64.hpp>
+#include <xmltooling/util/NDC.h>
+
+using namespace opensaml::saml2p;
+using namespace opensaml;
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace opensaml {
+ namespace saml2p {
+ MessageEncoder* SAML_DLLLOCAL SAML2POSTEncoderFactory(const DOMElement* const & e)
+ {
+ return new SAML2POSTEncoder(e);
+ }
+ };
+};
+
+SAML2POSTEncoder::SAML2POSTEncoder(const DOMElement* e) {}
+
+SAML2POSTEncoder::~SAML2POSTEncoder() {}
+
+void SAML2POSTEncoder::encode(
+ map<string,string>& outputFields,
+ XMLObject* xmlObject,
+ const char* recipientID,
+ const char* relayState,
+ const CredentialResolver* credResolver,
+ const XMLCh* sigAlgorithm
+ ) const
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("encode");
+#endif
+ Category& log = Category::getInstance(SAML_LOGCAT".MessageEncoder.SAML2POST");
+ log.debug("validating input");
+
+ outputFields.clear();
+ if (xmlObject->getParent())
+ throw BindingException("Cannot encode XML content with parent.");
+
+ StatusResponseType* response = NULL;
+ RequestAbstractType* request = dynamic_cast<RequestAbstractType*>(xmlObject);
+ if (!request)
+ response = dynamic_cast<StatusResponseType*>(xmlObject);
+ if (!response)
+ throw BindingException("XML content for SAML 2.0 HTTP-POST Encoder must be a SAML 2.0 protocol message.");
+
+ DOMElement* rootElement = NULL;
+ if (credResolver) {
+ // Signature based on native XML signing.
+ if (request ? request->getSignature() : response->getSignature()) {
+ log.debug("message already signed, skipping signature operation");
+ }
+ else {
+ log.debug("signing and marshalling the message");
+
+ // Build a Signature.
+ Signature* sig = buildSignature(credResolver, sigAlgorithm);
+
+ // Append Signature.
+ request ? request->setSignature(sig) : response->setSignature(sig);
+
+ // Sign response while marshalling.
+ vector<Signature*> sigs(1,sig);
+ rootElement = xmlObject->marshall((DOMDocument*)NULL,&sigs);
+ }
+ }
+ else {
+ log.debug("marshalling the message");
+ rootElement = xmlObject->marshall();
+ }
+
+ string xmlbuf;
+ XMLHelper::serialize(rootElement, xmlbuf);
+ unsigned int len=0;
+ XMLByte* out=Base64::encode(reinterpret_cast<const XMLByte*>(xmlbuf.data()),xmlbuf.size(),&len);
+ if (out) {
+ xmlbuf.erase();
+ xmlbuf.append(reinterpret_cast<char*>(out),len);
+ XMLString::release(&out);
+ }
+ else {
+ throw BindingException("Base64 encoding of XML failed.");
+ }
+
+ // Pass back output fields.
+ outputFields[request ? "SAMLRequest" : "SAMLResponse"] = xmlbuf;
+ if (relayState)
+ outputFields["RelayState"] = relayState;
+
+ // Cleanup by destroying XML.
+ delete xmlObject;
+
+ log.debug("message encoded");
+}