https://issues.shibboleth.net/jira/browse/SSPCPP-249
authorScott Cantor <cantor.2@osu.edu>
Mon, 2 Nov 2009 19:58:23 +0000 (19:58 +0000)
committerScott Cantor <cantor.2@osu.edu>
Mon, 2 Nov 2009 19:58:23 +0000 (19:58 +0000)
schemas/shibboleth-2.0-attribute-map.xsd
shibsp/attribute/Attribute.cpp
shibsp/attribute/AttributeDecoder.h
shibsp/attribute/KeyInfoAttributeDecoder.cpp

index c3ebdba..4fa9883 100644 (file)
                 <documentation>Flag controlling whether the resulting attribute should be exported for CGI use.</documentation>
             </annotation>
         </attribute>
+        <attribute name="hashAlg" type="am:string">
+            <annotation>
+                <documentation>
+                    Crypto-provider-specific name of hash algorithm to use,
+                    turning the decoded result into a simple string.
+                </documentation>
+            </annotation>
+        </attribute>
     </complexType>
     
     <complexType name="StringAttributeDecoder">
                         </documentation>
                     </annotation>
                 </attribute>
-                <attribute name="hashAlg" type="am:string">
+                <attribute name="keyInfoHashAlg" type="am:string">
                     <annotation>
                         <documentation>
                             Crypto-provider-specific name of hash algorithm to use.
index 70bff1f..8b99f45 100644 (file)
@@ -34,6 +34,7 @@
 #include "util/SPConstants.h"
 
 #include <xercesc/util/XMLUniDefs.hpp>
+#include <xmltooling/security/SecurityHelper.h>
 
 using namespace shibsp;
 using namespace xmltooling;
@@ -64,6 +65,7 @@ namespace shibsp {
     static const XMLCh _XMLAttributeDecoder[] =    UNICODE_LITERAL_19(X,M,L,A,t,t,r,i,b,u,t,e,D,e,c,o,d,e,r);
 
     static const XMLCh caseSensitive[] =           UNICODE_LITERAL_13(c,a,s,e,S,e,n,s,i,t,i,v,e);
+    static const XMLCh hashAlg[] =                 UNICODE_LITERAL_7(h,a,s,h,A,l,g);
     static const XMLCh internal[] =                UNICODE_LITERAL_8(i,n,t,e,r,n,a,l);
 #endif
 };
@@ -89,7 +91,8 @@ void shibsp::registerAttributeDecoders()
     conf.AttributeDecoderManager.registerFactory(XMLAttributeDecoderType, XMLAttributeDecoderFactory);
 }
 
-AttributeDecoder::AttributeDecoder(const DOMElement *e) : m_caseSensitive(true), m_internal(false)
+AttributeDecoder::AttributeDecoder(const DOMElement *e)
+    : m_caseSensitive(true), m_internal(false), m_hashAlg(e ? e->getAttributeNS(NULL, hashAlg) : NULL)
 {
     if (e) {
         const XMLCh* flag = e->getAttributeNS(NULL, caseSensitive);
@@ -108,8 +111,27 @@ AttributeDecoder::~AttributeDecoder()
 
 Attribute* AttributeDecoder::_decode(Attribute* attr) const
 {
-    attr->setCaseSensitive(m_caseSensitive);
-    attr->setInternal(m_internal);
+    if (attr) {
+        attr->setCaseSensitive(m_caseSensitive);
+        attr->setInternal(m_internal);
+
+        if (m_hashAlg.get() && *m_hashAlg.get()) {
+            // We turn the values into strings using the supplied hash algorithm and return a SimpleAttribute instead.
+            auto_ptr<SimpleAttribute> simple(new SimpleAttribute(attr->getAliases()));
+            simple->setCaseSensitive(false);
+            simple->setInternal(m_internal);
+            vector<string>& newdest = simple->getValues();
+            const vector<string>& serialized = attr->getSerializedValues();
+            for (vector<string>::const_iterator ser = serialized.begin(); ser != serialized.end(); ++ser) {
+                newdest.push_back(SecurityHelper::doHash(m_hashAlg.get(), ser->data(), ser->length()));
+                if (newdest.back().empty())
+                    newdest.pop_back();
+            }
+            delete attr;
+            return newdest.empty() ? NULL : simple.release();
+        }
+
+    }
     return attr;
 }
 #endif
index 01f055b..a4ffd04 100644 (file)
@@ -57,6 +57,9 @@ namespace shibsp {
         /** Flag for hiding attributes from CGI export. */
         bool m_internal;
 
+        /** Hash algorithm to apply to decoded values. */
+        xmltooling::auto_ptr_char m_hashAlg;
+
         /**
          * Helper method to handle base class decoding housekeeping.
          *
index b566302..741d5da 100644 (file)
@@ -55,7 +55,7 @@ namespace shibsp {
         void extract(const KeyInfo* k, vector<string>& dest) const {
             auto_ptr<Credential> cred (getKeyInfoResolver()->resolve(k, Credential::RESOLVE_KEYS));
             if (cred.get()) {
-                const char* alg = m_hashAlg.get();
+                const char* alg = m_keyInfoHashAlg.get();
                 if (!alg || !*alg)
                     alg = "SHA1";
                 dest.push_back(string());
@@ -70,7 +70,7 @@ namespace shibsp {
         }
 
         bool m_hash;
-        auto_ptr_char m_hashAlg;
+        auto_ptr_char m_keyInfoHashAlg;
         KeyInfoResolver* m_keyInfoResolver;
     };
 
@@ -81,12 +81,15 @@ namespace shibsp {
 
     static const XMLCh _KeyInfoResolver[] = UNICODE_LITERAL_15(K,e,y,I,n,f,o,R,e,s,o,l,v,e,r);
     static const XMLCh _hash[] =            UNICODE_LITERAL_4(h,a,s,h);
-    static const XMLCh _hashAlg[] =         UNICODE_LITERAL_7(h,a,s,h,A,l,g);
+    static const XMLCh keyInfoHashAlg[] =   UNICODE_LITERAL_14(k,e,y,I,n,f,o,H,a,s,h,A,l,g);
     static const XMLCh _type[] =            UNICODE_LITERAL_4(t,y,p,e);
 };
 
 KeyInfoAttributeDecoder::KeyInfoAttributeDecoder(const DOMElement* e)
-        : AttributeDecoder(e), m_hash(false), m_hashAlg(e ? e->getAttributeNS(NULL, _hashAlg) : NULL), m_keyInfoResolver(NULL) {
+        : AttributeDecoder(e),
+          m_hash(false),
+          m_keyInfoHashAlg(e ? e->getAttributeNS(NULL, keyInfoHashAlg) : NULL),
+          m_keyInfoResolver(NULL) {
     const XMLCh* flag = e ? e->getAttributeNS(NULL, _hash) : NULL;
     m_hash = (flag && (*flag == chLatin_t || *flag == chDigit_1));
     e = e ? XMLHelper::getFirstChildElement(e,_KeyInfoResolver) : NULL;