Altered SimpleSign logic to reflect change to draft spec.
authorScott Cantor <cantor.2@osu.edu>
Tue, 16 Jan 2007 20:17:30 +0000 (20:17 +0000)
committerScott Cantor <cantor.2@osu.edu>
Tue, 16 Jan 2007 20:17:30 +0000 (20:17 +0000)
saml/binding/impl/SimpleSigningRule.cpp
saml/saml2/binding/impl/SAML2POSTEncoder.cpp

index 8acc34b..5b888ee 100644 (file)
@@ -29,6 +29,7 @@
 #include "saml2/metadata/MetadataProvider.h"
 
 #include <log4cpp/Category.hh>
+#include <xercesc/util/Base64.hpp>
 
 using namespace opensaml::saml2md;
 using namespace opensaml;
@@ -100,6 +101,10 @@ void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest*
         // We have to construct a string containing the signature input by accessing the
         // request directly. We can't use the decoded parameters because we need the raw
         // data and URL-encoding isn't canonical.
+
+        // NOTE: SimpleSign for GET means Redirect binding, which means we verify over the
+        // base64-encoded message directly.
+
         pch = httpRequest->getQueryString();
         if (!appendParameter(input, pch, "SAMLRequest="))
             appendParameter(input, pch, "SAMLResponse=");
@@ -109,13 +114,34 @@ void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest*
     else {
         // With POST, the input string is concatenated from the decoded form controls.
         // GET should be this way too, but I messed up the spec, sorry.
+
+        // NOTE: SimpleSign for POST means POST binding, which means we verify over the
+        // base64-decoded XML. This sucks, because we have to decode the base64 directly.
+        // Serializing the XMLObject doesn't guarantee the signature will verify (this is
+        // why XMLSignature exists, and why this isn't really "simpler").
+
+        unsigned int x;
         pch = httpRequest->getParameter("SAMLRequest");
-        if (pch)
-            input = string("SAMLRequest=") + pch;
+        if (pch) {
+            XMLByte* decoded=Base64::decode(reinterpret_cast<const XMLByte*>(pch),&x);
+            if (!decoded) {
+                log.warn("unable to decode base64 in POST binding message");
+                return;
+            }
+            input = string("SAMLRequest=") + reinterpret_cast<const char*>(decoded);
+            XMLString::release(&decoded);
+        }
         else {
             pch = httpRequest->getParameter("SAMLResponse");
-            input = string("SAMLResponse=") + pch;
+            XMLByte* decoded=Base64::decode(reinterpret_cast<const XMLByte*>(pch),&x);
+            if (!decoded) {
+                log.warn("unable to decode base64 in POST binding message");
+                return;
+            }
+            input = string("SAMLResponse=") + reinterpret_cast<const char*>(decoded);
+            XMLString::release(&decoded);
         }
+
         pch = httpRequest->getParameter("RelayState");
         if (pch)
             input = input + "&RelayState=" + pch;
index 31c57d6..b1b45c9 100644 (file)
@@ -124,17 +124,11 @@ long SAML2POSTEncoder::encode(
     if (relayState)
         pmap.m_map["RelayState"] = relayState;
 
-    // Base64 the message.
+    // Serialize the message.
     string& msg = pmap.m_map[(request ? "SAMLRequest" : "SAMLResponse")];
     XMLHelper::serialize(rootElement, msg);
-    unsigned int len=0;
-    XMLByte* out=Base64::encode(reinterpret_cast<const XMLByte*>(msg.data()),msg.size(),&len);
-    if (!out)
-        throw BindingException("Base64 encoding of XML failed.");
-    msg.erase();
-    msg.append(reinterpret_cast<char*>(out),len);
-    XMLString::release(&out);
-    
+
+    // SimpleSign.
     if (credResolver && m_simple) {
         log.debug("applying simple signature to message data");
         string input = (request ? "SAMLRequest=" : "SAMLResponse=") + msg;
@@ -153,6 +147,15 @@ long SAML2POSTEncoder::encode(
         pmap.m_map["Signature"] = sigbuf;
     }
     
+    // Base64 the message.
+    unsigned int len=0;
+    XMLByte* out=Base64::encode(reinterpret_cast<const XMLByte*>(msg.data()),msg.size(),&len);
+    if (!out)
+        throw BindingException("Base64 encoding of XML failed.");
+    msg.erase();
+    msg.append(reinterpret_cast<char*>(out),len);
+    XMLString::release(&out);
+    
     // Push message into template and send result to client.
     log.debug("message encoded, sending HTML form template to client");
     TemplateEngine* engine = XMLToolingConfig::getConfig().getTemplateEngine();