Added epoch caching for DateTime attributes.
authorScott Cantor <cantor.2@osu.edu>
Fri, 7 Jul 2006 03:30:51 +0000 (03:30 +0000)
committerScott Cantor <cantor.2@osu.edu>
Fri, 7 Jul 2006 03:30:51 +0000 (03:30 +0000)
saml/saml1/core/impl/AssertionsImpl.cpp
saml/saml1/core/impl/ProtocolsImpl.cpp
saml/saml2/core/impl/Assertions20Impl.cpp
saml/saml2/core/impl/Protocols20Impl.cpp
saml/saml2/metadata/Metadata.h
saml/saml2/metadata/impl/MetadataImpl.cpp

index 5edb41b..099bdcc 100644 (file)
@@ -168,8 +168,8 @@ namespace opensaml {
             }
             
             IMPL_XMLOBJECT_CLONE(Conditions);
-            IMPL_DATETIME_ATTRIB(NotBefore);
-            IMPL_DATETIME_ATTRIB(NotOnOrAfter);
+            IMPL_DATETIME_ATTRIB(NotBefore,0);
+            IMPL_DATETIME_ATTRIB(NotOnOrAfter,LLONG_MAX);
             IMPL_TYPED_CHILDREN(AudienceRestrictionCondition, m_children.end());
             IMPL_TYPED_CHILDREN(DoNotCacheCondition,m_children.end());
             IMPL_TYPED_CHILDREN(Condition,m_children.end());
@@ -548,7 +548,7 @@ namespace opensaml {
                 return cloneAuthenticationStatement();
             }
             IMPL_STRING_ATTRIB(AuthenticationMethod);
-            IMPL_DATETIME_ATTRIB(AuthenticationInstant);
+            IMPL_DATETIME_ATTRIB(AuthenticationInstant,0);
             IMPL_TYPED_CHILD(SubjectLocality);
             IMPL_TYPED_CHILDREN(AuthorityBinding, m_children.end());
     
@@ -1053,7 +1053,7 @@ namespace opensaml {
             IMPL_INTEGER_ATTRIB(MinorVersion);
             IMPL_STRING_ATTRIB(AssertionID);
             IMPL_STRING_ATTRIB(Issuer);
-            IMPL_DATETIME_ATTRIB(IssueInstant);
+            IMPL_DATETIME_ATTRIB(IssueInstant,0);
             IMPL_TYPED_CHILD(Conditions);
             IMPL_TYPED_CHILD(Advice);
             IMPL_TYPED_CHILDREN(Statement, m_pos_Signature);
@@ -1073,8 +1073,10 @@ namespace opensaml {
                     const_cast<AssertionImpl*>(this)->m_AssertionID=SAMLConfig::getConfig().generateIdentifier();
                 MARSHALL_ID_ATTRIB(AssertionID,ASSERTIONID,NULL);
                 MARSHALL_STRING_ATTRIB(Issuer,ISSUER,NULL);
-                if (!m_IssueInstant)
-                    const_cast<AssertionImpl*>(this)->m_IssueInstant=new DateTime(time(NULL));
+                if (!m_IssueInstant) {
+                    const_cast<AssertionImpl*>(this)->m_IssueInstantEpoch=time(NULL);
+                    const_cast<AssertionImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
+                }
                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
             }
     
index 2ea517d..ee6969b 100644 (file)
@@ -372,7 +372,7 @@ namespace opensaml {
 
             IMPL_INTEGER_ATTRIB(MinorVersion);
             IMPL_STRING_ATTRIB(RequestID);
-            IMPL_DATETIME_ATTRIB(IssueInstant);
+            IMPL_DATETIME_ATTRIB(IssueInstant,0);
             IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature);
     
         protected:
@@ -385,8 +385,10 @@ namespace opensaml {
                 if (!m_RequestID)
                     const_cast<RequestAbstractTypeImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
                 MARSHALL_ID_ATTRIB(RequestID,REQUESTID,NULL);
-                if (!m_IssueInstant)
-                    const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(time(NULL));
+                if (!m_IssueInstant) {
+                    const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(NULL);
+                    const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
+                }
                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
             }
 
@@ -697,7 +699,7 @@ namespace opensaml {
             IMPL_INTEGER_ATTRIB(MinorVersion);
             IMPL_STRING_ATTRIB(ResponseID);
             IMPL_STRING_ATTRIB(InResponseTo);
-            IMPL_DATETIME_ATTRIB(IssueInstant);
+            IMPL_DATETIME_ATTRIB(IssueInstant,0);
             IMPL_STRING_ATTRIB(Recipient);
     
         protected:
@@ -711,8 +713,10 @@ namespace opensaml {
                     const_cast<ResponseAbstractTypeImpl*>(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier();
                 MARSHALL_ID_ATTRIB(ResponseID,RESPONSEID,NULL);
                 MARSHALL_STRING_ATTRIB(InResponseTo,INRESPONSETO,NULL);
-                if (!m_IssueInstant)
-                    const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(time(NULL));
+                if (!m_IssueInstant) {
+                    const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(NULL);
+                    const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
+                }
                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
                 MARSHALL_STRING_ATTRIB(Recipient,RECIPIENT,NULL);
             }
index 7b3ec9a..9bf85e2 100644 (file)
@@ -412,8 +412,8 @@ namespace opensaml {
             }
                         
             IMPL_XMLOBJECT_CLONE(Conditions);
-            IMPL_DATETIME_ATTRIB(NotBefore);
-            IMPL_DATETIME_ATTRIB(NotOnOrAfter);
+            IMPL_DATETIME_ATTRIB(NotBefore,0);
+            IMPL_DATETIME_ATTRIB(NotOnOrAfter,LLONG_MAX);
             IMPL_TYPED_CHILDREN(AudienceRestriction, m_children.end());
             IMPL_TYPED_CHILDREN(OneTimeUse,m_children.end());
             IMPL_TYPED_CHILDREN(ProxyRestriction, m_children.end());
@@ -472,8 +472,8 @@ namespace opensaml {
             }
             
             IMPL_XMLOBJECT_CLONE(SubjectConfirmationData);
-            IMPL_DATETIME_ATTRIB(NotBefore);
-            IMPL_DATETIME_ATTRIB(NotOnOrAfter);
+            IMPL_DATETIME_ATTRIB(NotBefore,0);
+            IMPL_DATETIME_ATTRIB(NotOnOrAfter,LLONG_MAX);
             IMPL_STRING_ATTRIB(Recipient);
             IMPL_STRING_ATTRIB(InResponseTo);
             IMPL_STRING_ATTRIB(Address);
@@ -564,8 +564,8 @@ namespace opensaml {
             }
             
             IMPL_XMLOBJECT_CLONE(KeyInfoConfirmationDataType);
-            IMPL_DATETIME_ATTRIB(NotBefore);
-            IMPL_DATETIME_ATTRIB(NotOnOrAfter);
+            IMPL_DATETIME_ATTRIB(NotBefore,0);
+            IMPL_DATETIME_ATTRIB(NotOnOrAfter,LLONG_MAX);
             IMPL_STRING_ATTRIB(Recipient);
             IMPL_STRING_ATTRIB(InResponseTo);
             IMPL_STRING_ATTRIB(Address);
@@ -944,9 +944,9 @@ namespace opensaml {
             Statement* cloneStatement() const {
                 return cloneAuthnStatement();
             }
-            IMPL_DATETIME_ATTRIB(AuthnInstant);
+            IMPL_DATETIME_ATTRIB(AuthnInstant,0);
             IMPL_STRING_ATTRIB(SessionIndex);
-            IMPL_DATETIME_ATTRIB(SessionNotOnOrAfter);
+            IMPL_DATETIME_ATTRIB(SessionNotOnOrAfter,LLONG_MAX);
             IMPL_TYPED_CHILD(SubjectLocality);
             IMPL_TYPED_CHILD(AuthnContext);
     
@@ -1520,7 +1520,7 @@ namespace opensaml {
             IMPL_XMLOBJECT_CLONE(Assertion);
             IMPL_STRING_ATTRIB(Version);
             IMPL_STRING_ATTRIB(ID);
-            IMPL_DATETIME_ATTRIB(IssueInstant);
+            IMPL_DATETIME_ATTRIB(IssueInstant,0);
             IMPL_TYPED_CHILD(Issuer);
             IMPL_TYPED_CHILD(Subject);
             IMPL_TYPED_CHILD(Conditions);
@@ -1538,8 +1538,10 @@ namespace opensaml {
                 if (!m_ID)
                     const_cast<AssertionImpl*>(this)->m_ID=SAMLConfig::getConfig().generateIdentifier();
                 MARSHALL_ID_ATTRIB(ID,ID,NULL);
-                if (!m_IssueInstant)
-                    const_cast<AssertionImpl*>(this)->m_IssueInstant=new DateTime(time(NULL));
+                if (!m_IssueInstant) {
+                    const_cast<AssertionImpl*>(this)->m_IssueInstantEpoch=time(NULL);
+                    const_cast<AssertionImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
+                }
                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
             }
     
index 8f4a3d6..ea2cb01 100644 (file)
@@ -338,7 +338,7 @@ namespace opensaml {
             IMPL_XMLOBJECT_CLONE(Request);
             IMPL_STRING_ATTRIB(Version);
             IMPL_STRING_ATTRIB(ID);
-            IMPL_DATETIME_ATTRIB(IssueInstant);
+            IMPL_DATETIME_ATTRIB(IssueInstant,0);
             IMPL_STRING_ATTRIB(Destination);
             IMPL_STRING_ATTRIB(Consent);
             IMPL_TYPED_FOREIGN_CHILD(Issuer,saml2);
@@ -352,8 +352,10 @@ namespace opensaml {
                 if (!m_ID)
                     const_cast<RequestImpl*>(this)->m_ID=SAMLConfig::getConfig().generateIdentifier();
                 MARSHALL_ID_ATTRIB(ID,ID,NULL);
-                if (!m_IssueInstant)
-                    const_cast<RequestImpl*>(this)->m_IssueInstant=new DateTime(time(NULL));
+                if (!m_IssueInstant) {
+                    const_cast<RequestImpl*>(this)->m_IssueInstantEpoch=time(NULL);
+                    const_cast<RequestImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
+                }
                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
                 MARSHALL_STRING_ATTRIB(Destination,DESTINATION,NULL);
                 MARSHALL_STRING_ATTRIB(Consent,CONSENT,NULL);
@@ -1109,7 +1111,7 @@ namespace opensaml {
             IMPL_STRING_ATTRIB(Version);
             IMPL_STRING_ATTRIB(ID);
             IMPL_STRING_ATTRIB(InResponseTo);
-            IMPL_DATETIME_ATTRIB(IssueInstant);
+            IMPL_DATETIME_ATTRIB(IssueInstant,0);
             IMPL_STRING_ATTRIB(Destination);
             IMPL_STRING_ATTRIB(Consent);
             IMPL_TYPED_FOREIGN_CHILD(Issuer,saml2);
@@ -1124,8 +1126,10 @@ namespace opensaml {
                 if (!m_ID)
                     const_cast<StatusResponseImpl*>(this)->m_ID=SAMLConfig::getConfig().generateIdentifier();
                 MARSHALL_ID_ATTRIB(ID,ID,NULL);
-                if (!m_IssueInstant)
-                    const_cast<StatusResponseImpl*>(this)->m_IssueInstant=new DateTime(time(NULL));
+                if (!m_IssueInstant) {
+                    const_cast<StatusResponseImpl*>(this)->m_IssueInstantEpoch=time(NULL);
+                    const_cast<StatusResponseImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
+                }
                 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL);
                 MARSHALL_STRING_ATTRIB(Destination,DESTINATION,NULL);
                 MARSHALL_STRING_ATTRIB(Consent,CONSENT,NULL);
@@ -1519,7 +1523,7 @@ namespace opensaml {
             IMPL_XMLOBJECT_CLONE(LogoutRequest);
 
             IMPL_STRING_ATTRIB(Reason);
-            IMPL_DATETIME_ATTRIB(NotOnOrAfter);
+            IMPL_DATETIME_ATTRIB(NotOnOrAfter,LLONG_MAX);
             IMPL_TYPED_FOREIGN_CHILD(BaseID,saml2);
             IMPL_TYPED_FOREIGN_CHILD(NameID,saml2);
             IMPL_TYPED_FOREIGN_CHILD(EncryptedID,saml2);
index 60445d8..528a9d6 100644 (file)
@@ -26,6 +26,7 @@
 #include <saml/saml2/core/Assertions.h>
 #include <saml/util/SAMLConstants.h>
 
+#include <ctime>
 #include <xmltooling/AttributeExtensibleXMLObject.h>
 #include <xmltooling/ElementProxy.h>
 #include <xmltooling/SimpleElement.h>
@@ -47,6 +48,34 @@ namespace opensaml {
      */
     namespace saml2md {
         
+        /**
+         * Base class for metadata objects that feature a cacheDuration attribute.
+         */
+        class SAML_API CacheableSAMLObject : public virtual xmltooling::XMLObject
+        {
+        protected:
+            CacheableSAMLObject() {}
+        public:
+            ~CacheableSAMLObject() {}
+            DECL_DATETIME_ATTRIB(CacheDuration,CACHEDURATION);
+        };
+
+        /**
+         * Base class for metadata objects that feature a validUntil attribute.
+         */
+        class SAML_API TimeBoundSAMLObject : public virtual xmltooling::XMLObject
+        {
+        protected:
+            TimeBoundSAMLObject() {}
+        public:
+            ~TimeBoundSAMLObject() {}
+            DECL_DATETIME_ATTRIB(ValidUntil,VALIDUNTIL);
+            /** Returns true iff the object is valid at the current time. */
+            bool isValid() const {
+                return time(NULL) <= getValidUntilEpoch();
+            }
+        };
+
         DECL_XMLOBJECT_SIMPLE(SAML_API,AffiliateMember,ID,SAML 2.0 AffiliateMember element);
         DECL_XMLOBJECT_SIMPLE(SAML_API,AttributeProfile,ProfileURI,SAML 2.0 AttributeProfile element);
         DECL_XMLOBJECT_SIMPLE(SAML_API,Company,Name,SAML 2.0 Company element);
@@ -135,11 +164,12 @@ namespace opensaml {
             static const XMLCh KEYTYPE_SIGNING[];
         END_XMLOBJECT;
 
-        BEGIN_XMLOBJECT2(SAML_API,RoleDescriptor,xmltooling::AttributeExtensibleXMLObject,SignableObject,SAML 2.0 RoleDescriptor abstract element);
+        BEGIN_XMLOBJECT4(SAML_API,RoleDescriptor,xmltooling::AttributeExtensibleXMLObject,SignableObject,
+                CacheableSAMLObject,TimeBoundSAMLObject,SAML 2.0 RoleDescriptor abstract element);
             DECL_STRING_ATTRIB(ID,ID);
-            DECL_DATETIME_ATTRIB(ValidUntil,VALIDUNTIL);
-            DECL_DATETIME_ATTRIB(CacheDuration,CACHEDURATION);
             DECL_STRING_ATTRIB(ProtocolSupportEnumeration,PROTOCOLSUPPORTENUMERATION);
+            /** Searches the ProtocolSupportEnumeration attribute for the indicated protocol. */
+            virtual bool hasSupport(const XMLCh* protocol) const=0;
             DECL_STRING_ATTRIB(ErrorURL,ERRORURL);
             DECL_TYPED_FOREIGN_CHILD(Signature,xmlsignature);
             DECL_TYPED_CHILD(Extensions);
@@ -272,11 +302,10 @@ namespace opensaml {
             static const XMLCh TYPE_NAME[];
         END_XMLOBJECT;
 
-        BEGIN_XMLOBJECT2(SAML_API,AffiliationDescriptor,xmltooling::AttributeExtensibleXMLObject,SignableObject,SAML 2.0 AffiliationDescriptor element);
+        BEGIN_XMLOBJECT4(SAML_API,AffiliationDescriptor,xmltooling::AttributeExtensibleXMLObject,SignableObject,
+                CacheableSAMLObject,TimeBoundSAMLObject,SAML 2.0 AffiliationDescriptor element);
             DECL_STRING_ATTRIB(ID,ID);
             DECL_STRING_ATTRIB(AffiliationOwnerID,AFFILIATIONOWNERID);
-            DECL_DATETIME_ATTRIB(ValidUntil,VALIDUNTIL);
-            DECL_DATETIME_ATTRIB(CacheDuration,CACHEDURATION);
             DECL_TYPED_FOREIGN_CHILD(Signature,xmlsignature);
             DECL_TYPED_CHILD(Extensions);
             DECL_TYPED_CHILDREN(AffiliateMember);
@@ -285,11 +314,10 @@ namespace opensaml {
             static const XMLCh TYPE_NAME[];
         END_XMLOBJECT;
 
-        BEGIN_XMLOBJECT2(SAML_API,EntityDescriptor,xmltooling::AttributeExtensibleXMLObject,SignableObject,SAML 2.0 EntityDescriptor element);
+        BEGIN_XMLOBJECT4(SAML_API,EntityDescriptor,xmltooling::AttributeExtensibleXMLObject,SignableObject,
+                CacheableSAMLObject,TimeBoundSAMLObject,SAML 2.0 EntityDescriptor element);
             DECL_STRING_ATTRIB(ID,ID);
             DECL_STRING_ATTRIB(EntityID,ENTITYID);
-            DECL_DATETIME_ATTRIB(ValidUntil,VALIDUNTIL);
-            DECL_DATETIME_ATTRIB(CacheDuration,CACHEDURATION);
             DECL_TYPED_FOREIGN_CHILD(Signature,xmlsignature);
             DECL_TYPED_CHILD(Extensions);
             DECL_TYPED_CHILD(AffiliationDescriptor);
@@ -303,11 +331,10 @@ namespace opensaml {
             static const XMLCh TYPE_NAME[];
         END_XMLOBJECT;
 
-        BEGIN_XMLOBJECT(SAML_API,EntitiesDescriptor,SignableObject,SAML 2.0 EntitiesDescriptor element);
+        BEGIN_XMLOBJECT3(SAML_API,EntitiesDescriptor,SignableObject,CacheableSAMLObject,
+                TimeBoundSAMLObject,SAML 2.0 EntitiesDescriptor element);
             DECL_STRING_ATTRIB(ID,ID);
             DECL_STRING_ATTRIB(Name,NAME);
-            DECL_DATETIME_ATTRIB(ValidUntil,VALIDUNTIL);
-            DECL_DATETIME_ATTRIB(CacheDuration,CACHEDURATION);
             DECL_TYPED_FOREIGN_CHILD(Signature,xmlsignature);
             DECL_TYPED_CHILD(Extensions);
             DECL_TYPED_CHILDREN(EntityDescriptor);
index 9a86aab..46f6d06 100644 (file)
@@ -578,7 +578,7 @@ namespace opensaml {
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
                 PROC_TYPED_FOREIGN_CHILD(KeyInfo,xmlsignature,XMLConstants::XMLSIG_NS,false);
-                PROC_TYPED_FOREIGN_CHILDREN(EncryptionMethod,xmlencryption,XMLConstants::XMLENC_NS,false);
+                PROC_TYPED_FOREIGN_CHILDREN(EncryptionMethod,xmlencryption,SAMLConstants::SAML20MD_NS,false);
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
             }
 
@@ -1013,12 +1013,44 @@ namespace opensaml {
             IMPL_STRING_ATTRIB(ID);
             IMPL_STRING_ATTRIB(ProtocolSupportEnumeration);
             IMPL_STRING_ATTRIB(ErrorURL);
-            IMPL_DATETIME_ATTRIB(ValidUntil);
-            IMPL_DATETIME_ATTRIB(CacheDuration);
+            IMPL_DATETIME_ATTRIB(ValidUntil,LLONG_MAX);
+            IMPL_DATETIME_ATTRIB(CacheDuration,0);
             IMPL_TYPED_CHILD(Extensions);
             IMPL_TYPED_CHILDREN(KeyDescriptor,m_pos_Organization);
             IMPL_TYPED_CHILD(Organization);
             IMPL_TYPED_CHILDREN(ContactPerson,m_pos_ContactPerson);
+
+            bool hasSupport(const XMLCh* protocol) const {
+                if (m_ProtocolSupportEnumeration) {
+                    // Look for first character.
+                    unsigned int len=XMLString::stringLen(protocol);
+                    unsigned int pos=0;
+                    int index=XMLString::indexOf(m_ProtocolSupportEnumeration,protocol[0],pos);
+                    while (index>=0) {
+                        // Only possible match is if it's the first character or a space comes before it.
+                        if (index==0 || m_ProtocolSupportEnumeration[index-1]==chSpace) {
+                            // See if rest of protocol string is present.
+                            if (0==XMLString::compareNString(m_ProtocolSupportEnumeration+index+1,protocol+1,len-1)) {
+                                // Only possible match is if it's the last character or a space comes after it.
+                                if (m_ProtocolSupportEnumeration[index+len+1]==chNull || m_ProtocolSupportEnumeration[index+len+1]==chSpace)
+                                    return true;
+                                else
+                                    pos=index+len+1;
+                            }
+                            else {
+                                // Move past last search and start again.
+                                pos=index+1;
+                            }
+                        }
+                        else {
+                            // Move past last search and start again.
+                            pos=index+1;
+                        }
+                        index=XMLString::indexOf(m_ProtocolSupportEnumeration,protocol[0],pos);
+                    }
+                }
+                return false;
+            }
     
             void setAttribute(QName& qualifiedName, const XMLCh* value) {
                 if (!qualifiedName.hasNamespaceURI()) {
@@ -1832,8 +1864,8 @@ namespace opensaml {
             
             IMPL_STRING_ATTRIB(ID);
             IMPL_STRING_ATTRIB(AffiliationOwnerID);
-            IMPL_DATETIME_ATTRIB(ValidUntil);
-            IMPL_DATETIME_ATTRIB(CacheDuration);
+            IMPL_DATETIME_ATTRIB(ValidUntil,LLONG_MAX);
+            IMPL_DATETIME_ATTRIB(CacheDuration,0);
             IMPL_TYPED_CHILD(Extensions);
             IMPL_TYPED_CHILDREN(AffiliateMember,m_pos_AffiliateMember);
             IMPL_TYPED_CHILDREN(KeyDescriptor,m_children.end());
@@ -2038,8 +2070,8 @@ namespace opensaml {
             
             IMPL_STRING_ATTRIB(ID);
             IMPL_STRING_ATTRIB(EntityID);
-            IMPL_DATETIME_ATTRIB(ValidUntil);
-            IMPL_DATETIME_ATTRIB(CacheDuration);
+            IMPL_DATETIME_ATTRIB(ValidUntil,LLONG_MAX);
+            IMPL_DATETIME_ATTRIB(CacheDuration,0);
             IMPL_TYPED_CHILD(Extensions);
             IMPL_TYPED_CHILDREN(RoleDescriptor,m_pos_AffiliationDescriptor);
             IMPL_TYPED_CHILDREN(IDPSSODescriptor,m_pos_AffiliationDescriptor);
@@ -2204,8 +2236,8 @@ namespace opensaml {
             
             IMPL_STRING_ATTRIB(ID);
             IMPL_STRING_ATTRIB(Name);
-            IMPL_DATETIME_ATTRIB(ValidUntil);
-            IMPL_DATETIME_ATTRIB(CacheDuration);
+            IMPL_DATETIME_ATTRIB(ValidUntil,LLONG_MAX);
+            IMPL_DATETIME_ATTRIB(CacheDuration,0);
             IMPL_TYPED_CHILD(Extensions);
             IMPL_TYPED_CHILDREN(EntityDescriptor,m_children.end());
             IMPL_TYPED_CHILDREN(EntitiesDescriptor,m_children.end());
@@ -2293,8 +2325,6 @@ const XMLCh AffiliateMember::LOCAL_NAME[] =             UNICODE_LITERAL_15(A,f,f
 const XMLCh AffiliationDescriptor::LOCAL_NAME[] =       UNICODE_LITERAL_21(A,f,f,i,l,i,a,t,i,o,n,D,e,s,c,r,i,p,t,o,r);
 const XMLCh AffiliationDescriptor::TYPE_NAME[] =        UNICODE_LITERAL_25(A,f,f,i,l,i,a,t,i,o,n,D,e,s,c,r,i,p,t,o,r,T,y,p,e);
 const XMLCh AffiliationDescriptor::ID_ATTRIB_NAME[] =   UNICODE_LITERAL_2(I,D);
-const XMLCh AffiliationDescriptor::VALIDUNTIL_ATTRIB_NAME[] =   UNICODE_LITERAL_10(v,a,l,i,d,U,n,t,i,l);
-const XMLCh AffiliationDescriptor::CACHEDURATION_ATTRIB_NAME[] =    UNICODE_LITERAL_13(c,a,c,h,e,D,u,r,a,t,i,o,n);
 const XMLCh AffiliationDescriptor::AFFILIATIONOWNERID_ATTRIB_NAME[] =   UNICODE_LITERAL_18(a,f,f,i,l,i,a,t,i,o,n,O,w,n,e,r,I,D);
 const XMLCh ArtifactResolutionService::LOCAL_NAME[] =   UNICODE_LITERAL_25(A,r,t,i,f,a,c,t,R,e,s,o,l,u,t,i,o,n,S,e,r,v,i,c,e);
 const XMLCh AssertionConsumerService::LOCAL_NAME[] =    UNICODE_LITERAL_24(A,s,s,e,r,t,i,o,n,C,o,n,s,u,m,e,r,S,e,r,v,i,c,e);
@@ -2311,6 +2341,7 @@ const XMLCh AuthnAuthorityDescriptor::LOCAL_NAME[] =    UNICODE_LITERAL_24(A,u,t
 const XMLCh AuthnAuthorityDescriptor::TYPE_NAME[] =     UNICODE_LITERAL_28(A,u,t,h,n,A,u,t,h,o,r,i,t,y,D,e,s,c,r,i,p,t,o,r,T,y,p,e);
 const XMLCh AuthnQueryService::LOCAL_NAME[] =           UNICODE_LITERAL_17(A,u,t,h,n,Q,u,e,r,y,S,e,r,v,i,c,e);
 const XMLCh AuthzService::LOCAL_NAME[] =                UNICODE_LITERAL_12(A,u,t,h,z,S,e,r,v,i,c,e);
+const XMLCh CacheableSAMLObject::CACHEDURATION_ATTRIB_NAME[] =  UNICODE_LITERAL_13(c,a,c,h,e,D,u,r,a,t,i,o,n);
 const XMLCh Company::LOCAL_NAME[] =                     UNICODE_LITERAL_7(C,o,m,p,a,n,y);
 const XMLCh ContactPerson::LOCAL_NAME[] =               UNICODE_LITERAL_13(C,o,n,t,a,c,t,P,e,r,s,o,n);
 const XMLCh ContactPerson::TYPE_NAME[] =                UNICODE_LITERAL_11(C,o,n,t,a,c,t,T,y,p,e);
@@ -2329,14 +2360,10 @@ const XMLCh EndpointType::RESPONSELOCATION_ATTRIB_NAME[] =  UNICODE_LITERAL_16(R
 const XMLCh EntitiesDescriptor::LOCAL_NAME[] =          UNICODE_LITERAL_18(E,n,t,i,t,i,e,s,D,e,s,c,r,i,p,t,o,r);
 const XMLCh EntitiesDescriptor::TYPE_NAME[] =           UNICODE_LITERAL_22(E,n,t,i,t,i,e,s,D,e,s,c,r,i,p,t,o,r,T,y,p,e);
 const XMLCh EntitiesDescriptor::ID_ATTRIB_NAME[] =      UNICODE_LITERAL_2(I,D);
-const XMLCh EntitiesDescriptor::VALIDUNTIL_ATTRIB_NAME[] =    UNICODE_LITERAL_10(v,a,l,i,d,U,n,t,i,l);
-const XMLCh EntitiesDescriptor::CACHEDURATION_ATTRIB_NAME[] = UNICODE_LITERAL_13(c,a,c,h,e,D,u,r,a,t,i,o,n);
 const XMLCh EntitiesDescriptor::NAME_ATTRIB_NAME[] =    UNICODE_LITERAL_4(N,a,m,e);
 const XMLCh EntityDescriptor::LOCAL_NAME[] =            UNICODE_LITERAL_16(E,n,t,i,t,y,D,e,s,c,r,i,p,t,o,r);
 const XMLCh EntityDescriptor::TYPE_NAME[] =             UNICODE_LITERAL_20(E,n,t,i,t,y,D,e,s,c,r,i,p,t,o,r,T,y,p,e);
 const XMLCh EntityDescriptor::ID_ATTRIB_NAME[] =        UNICODE_LITERAL_2(I,D);
-const XMLCh EntityDescriptor::VALIDUNTIL_ATTRIB_NAME[] =    UNICODE_LITERAL_10(v,a,l,i,d,U,n,t,i,l);
-const XMLCh EntityDescriptor::CACHEDURATION_ATTRIB_NAME[] = UNICODE_LITERAL_13(c,a,c,h,e,D,u,r,a,t,i,o,n);
 const XMLCh EntityDescriptor::ENTITYID_ATTRIB_NAME[] =  UNICODE_LITERAL_8(e,n,t,i,t,y,I,D);
 const XMLCh Extensions::LOCAL_NAME[] =                  UNICODE_LITERAL_10(E,x,t,e,n,s,i,o,n,s);
 const XMLCh Extensions::TYPE_NAME[] =                   UNICODE_LITERAL_14(E,x,t,e,n,s,i,o,n,s,T,y,p,e);
@@ -2374,8 +2401,6 @@ const XMLCh RequestedAttribute::TYPE_NAME[] =           UNICODE_LITERAL_22(R,e,q
 const XMLCh RequestedAttribute::ISREQUIRED_ATTRIB_NAME[] =  UNICODE_LITERAL_10(i,s,R,e,q,u,i,r,e,d);
 const XMLCh RoleDescriptor::LOCAL_NAME[] =              UNICODE_LITERAL_14(R,o,l,e,D,e,s,c,r,i,p,t,o,r);
 const XMLCh RoleDescriptor::ID_ATTRIB_NAME[] =          UNICODE_LITERAL_2(I,D);
-const XMLCh RoleDescriptor::VALIDUNTIL_ATTRIB_NAME[] =  UNICODE_LITERAL_10(v,a,l,i,d,U,n,t,i,l);
-const XMLCh RoleDescriptor::CACHEDURATION_ATTRIB_NAME[] =   UNICODE_LITERAL_13(c,a,c,h,e,D,u,r,a,t,i,o,n);
 const XMLCh RoleDescriptor::PROTOCOLSUPPORTENUMERATION_ATTRIB_NAME[] =  UNICODE_LITERAL_26(p,r,o,t,o,c,o,l,S,u,p,p,o,r,t,E,n,u,m,e,r,a,t,i,o,n);
 const XMLCh RoleDescriptor::ERRORURL_ATTRIB_NAME[] =    UNICODE_LITERAL_8(e,r,r,o,r,U,R,L);
 const XMLCh ServiceDescription::LOCAL_NAME[] =          UNICODE_LITERAL_18(S,e,r,v,i,c,e,D,e,s,c,r,i,p,t,i,o,n);
@@ -2390,3 +2415,4 @@ const XMLCh SSODescriptorType::LOCAL_NAME[] =           {chNull};
 const XMLCh SSODescriptorType::TYPE_NAME[] =            UNICODE_LITERAL_17(S,S,O,D,e,s,c,r,i,p,t,o,r,T,y,p,e);
 const XMLCh SurName::LOCAL_NAME[] =                     UNICODE_LITERAL_7(S,u,r,N,a,m,e);
 const XMLCh TelephoneNumber::LOCAL_NAME[] =             UNICODE_LITERAL_15(T,e,l,e,p,h,o,n,e,N,u,m,b,e,r);
+const XMLCh TimeBoundSAMLObject::VALIDUNTIL_ATTRIB_NAME[] =   UNICODE_LITERAL_10(v,a,l,i,d,U,n,t,i,l);