From: Scott Cantor Date: Mon, 12 Jun 2006 16:47:06 +0000 (+0000) Subject: Initial decryption and schema support for encrypted SAML. X-Git-Tag: 2.0-alpha1~244 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-opensaml.git;a=commitdiff_plain;h=034395d99c818fb5489421fd4e7aa4eb3fa5d173 Initial decryption and schema support for encrypted SAML. --- diff --git a/.cdtproject b/.cdtproject index 2358662..90f5f41 100644 --- a/.cdtproject +++ b/.cdtproject @@ -58,19 +58,20 @@ - - + + + - - - + + - + + diff --git a/saml/Makefile.am b/saml/Makefile.am index 20c354f..28ae43d 100644 --- a/saml/Makefile.am +++ b/saml/Makefile.am @@ -4,7 +4,9 @@ lib_LTLIBRARIES = libsaml.la libsamlincludedir = $(includedir)/saml -sigincludedir = $(includedir)/signature +encincludedir = $(includedir)/saml/encryption + +sigincludedir = $(includedir)/saml/signature utilincludedir = $(includedir)/saml/util @@ -13,18 +15,21 @@ saml1coreincludedir = $(includedir)/saml/saml1/core saml2coreincludedir = $(includedir)/saml/saml2/core libsamlinclude_HEADERS = \ - base.h \ - exceptions.h \ - version.h \ - SAMLConfig.h + base.h \ + exceptions.h \ + version.h \ + SAMLConfig.h + +encinclude_HEADERS = \ + encryption/EncryptedKeyResolver.h siginclude_HEADERS = \ - signature/ContentReference.h \ - signature/SignableObject.h \ - signature/SignatureProfileValidator.h + signature/ContentReference.h \ + signature/SignableObject.h \ + signature/SignatureProfileValidator.h utilinclude_HEADERS = \ - util/SAMLConstants.h + util/SAMLConstants.h saml1coreinclude_HEADERS = \ saml1/core/Assertions.h \ @@ -34,19 +39,20 @@ saml2coreinclude_HEADERS = \ saml2/core/Assertions.h noinst_HEADERS = \ - internal.h + internal.h libsaml_la_SOURCES = \ - SAMLConfig.cpp \ - saml1/core/impl/AssertionsImpl.cpp \ - saml1/core/impl/AssertionsSchemaValidators.cpp \ - saml1/core/impl/ProtocolsImpl.cpp \ - saml1/core/impl/ProtocolsSchemaValidators.cpp \ - saml2/core/impl/Assertions20Impl.cpp \ - saml2/core/impl/Assertions20SchemaValidators.cpp \ - signature/ContentReference.cpp \ - signature/SignatureProfileValidator.cpp \ - util/SAMLConstants.cpp + SAMLConfig.cpp \ + encryption/EncryptedKeyResolver.cpp \ + saml1/core/impl/AssertionsImpl.cpp \ + saml1/core/impl/AssertionsSchemaValidators.cpp \ + saml1/core/impl/ProtocolsImpl.cpp \ + saml1/core/impl/ProtocolsSchemaValidators.cpp \ + saml2/core/impl/Assertions20Impl.cpp \ + saml2/core/impl/Assertions20SchemaValidators.cpp \ + signature/ContentReference.cpp \ + signature/SignatureProfileValidator.cpp \ + util/SAMLConstants.cpp # this is different from the project version # http://sources.redhat.com/autobook/autobook/autobook_91.html diff --git a/saml/encryption/EncryptedKeyResolver.cpp b/saml/encryption/EncryptedKeyResolver.cpp new file mode 100644 index 0000000..5c9f652 --- /dev/null +++ b/saml/encryption/EncryptedKeyResolver.cpp @@ -0,0 +1,37 @@ +/* + * 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. + */ + +/** + * EncryptedKeyResolver.cpp + * + * SAML-specific encrypted key resolver + */ + +#include "internal.h" +#include "encryption/EncryptedKeyResolver.h" + +using namespace xmlencryption; +using namespace std; + +EncryptedKey* opensaml::EncryptedKeyResolver::resolveKey(EncryptedData* encryptedData) +{ + const vector& keys=m_ref.getEncryptedKeys(); + for (vector::const_iterator i=keys.begin(); i!=keys.end(); i++) { + if (XMLString::equals(m_recipient,(*i)->getRecipient())) + return (*i); + } + return NULL; +} diff --git a/saml/encryption/EncryptedKeyResolver.h b/saml/encryption/EncryptedKeyResolver.h new file mode 100644 index 0000000..cc6d2a2 --- /dev/null +++ b/saml/encryption/EncryptedKeyResolver.h @@ -0,0 +1,62 @@ +/* + * 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 EncryptedKeyResolver.h + * + * SAML-specific encrypted key resolver + */ + +#ifndef __saml_enckeyres_h__ +#define __saml_enckeyres_h__ + +#include +#include +#include + +namespace opensaml { + + /** + * SAML-specific encrypted key resolver. + * + * SAML allows placement of keys alongside the encrypted data. This resolver + * recognizes the implied placement. + */ + class SAML_API EncryptedKeyResolver : public xmlencryption::EncryptedKeyResolver + { + public: + EncryptedKeyResolver(const saml2::EncryptedElementType& ref, const XMLCh* recipient=NULL) + : m_ref(ref), m_recipient(XMLString::replicate(recipient)) { + } + + virtual ~EncryptedKeyResolver() { + XMLString::release(&m_recipient); + } + + xmlencryption::EncryptedKey* resolveKey(xmlencryption::EncryptedData* encryptedData); + + EncryptedKeyResolver* clone() const { + return new EncryptedKeyResolver(m_ref, m_recipient); + } + + protected: + const saml2::EncryptedElementType& m_ref; + XMLCh* m_recipient; + }; + +}; + +#endif /* __saml_enckeyres_h__ */ diff --git a/saml/saml.vcproj b/saml/saml.vcproj index 5e0939e..0bae7b3 100644 --- a/saml/saml.vcproj +++ b/saml/saml.vcproj @@ -261,6 +261,14 @@ + + + + + + + + getNamespaceURI(); - if (!XMLString::equals(nsURI,SAMLConstants::SAML1_NS) && nsURI && *nsURI) + if (!XMLString::equals(nsURI,SAMLConstants::SAML1_NS) && nsURI && *nsURI) { getOthers().push_back(childXMLObject); + return; + } AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); } diff --git a/saml/saml2/core/Assertions.h b/saml/saml2/core/Assertions.h index 1cc75be..a45b048 100644 --- a/saml/saml2/core/Assertions.h +++ b/saml/saml2/core/Assertions.h @@ -30,7 +30,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -56,6 +57,29 @@ namespace opensaml { DECL_XMLOBJECT_SIMPLE(SAML_API,AuthnContextDeclRef,Reference,SAML 2.0 AuthnContextDeclRef element); DECL_XMLOBJECT_SIMPLE(SAML_API,AuthenticatingAuthority,ID,SAML 2.0 AuthenticatingAuthority element); + BEGIN_XMLOBJECT(SAML_API,EncryptedElementType,xmltooling::XMLObject,SAML 2.0 EncryptedElementType type); + DECL_TYPED_FOREIGN_CHILD(EncryptedData,xmlencryption); + DECL_TYPED_FOREIGN_CHILDREN(EncryptedKey,xmlencryption); + /** EncryptedElementType local name */ + static const XMLCh TYPE_NAME[]; + + /** + * Decrypts the element using a standard approach based on a wrapped decryption key + * inside the message. The key decryption key should be supplied using the provided + * resolver. The recipient name may be used when multiple encrypted keys are found. + * The object returned will be unmarshalled around the decrypted DOM element, but the + * DOM itself will be released. + * + * @param KEKresolver resolver supplying key decryption key + * @param recipient identifier naming the recipient (the entity performing the decryption) + * @return the decrypted and unmarshalled object + */ + virtual xmltooling::XMLObject* decrypt(xmlsignature::KeyResolver* KEKresolver, const XMLCh* recipient) const=0; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(SAML_API,EncryptedID,EncryptedElementType,SAML 2.0 EncryptedID element); + END_XMLOBJECT; + BEGIN_XMLOBJECT(SAML_API,BaseID,xmltooling::XMLObject,SAML 2.0 BaseIDAbstractType abstract type); DECL_STRING_ATTRIB(NameQualifier,NAMEQUALIFIER); DECL_STRING_ATTRIB(SPNameQualifier,SPNAMEQUALIFIER); @@ -133,7 +157,7 @@ namespace opensaml { DECL_STRING_ATTRIB(Method,METHOD); DECL_TYPED_CHILD(BaseID); DECL_TYPED_CHILD(NameID); - //DECL_TYPED_CHILD(EncryptedID); + DECL_TYPED_CHILD(EncryptedID); DECL_XMLOBJECT_CHILD(SubjectConfirmationData); DECL_TYPED_CHILD(KeyInfoConfirmationDataType); /** SubjectConfirmationType local name */ @@ -143,7 +167,7 @@ namespace opensaml { BEGIN_XMLOBJECT(SAML_API,Subject,xmltooling::XMLObject,SAML 2.0 Subject element); DECL_TYPED_CHILD(BaseID); DECL_TYPED_CHILD(NameID); - //DECL_TYPED_CHILD(EncryptedID); + DECL_TYPED_CHILD(EncryptedID); DECL_TYPED_CHILDREN(SubjectConfirmation); /** SubjectType local name */ static const XMLCh TYPE_NAME[]; @@ -224,18 +248,24 @@ namespace opensaml { static const XMLCh TYPE_NAME[]; END_XMLOBJECT; + BEGIN_XMLOBJECT(SAML_API,EncryptedAttribute,EncryptedElementType,SAML 2.0 EncryptedAttribute element); + END_XMLOBJECT; + BEGIN_XMLOBJECT(SAML_API,AttributeStatement,Statement,SAML 2.0 AttributeStatement element); DECL_TYPED_CHILDREN(Attribute); - //DECL_TYPED_CHILDREN(EncryptedAttribute); + DECL_TYPED_CHILDREN(EncryptedAttribute); /** AttributeStatementType local name */ static const XMLCh TYPE_NAME[]; END_XMLOBJECT; + BEGIN_XMLOBJECT(SAML_API,EncryptedAssertion,EncryptedElementType,SAML 2.0 EncryptedAssertion element); + END_XMLOBJECT; + BEGIN_XMLOBJECT(SAML_API,Advice,xmltooling::XMLObject,SAML 2.0 Advice element); DECL_TYPED_CHILDREN(AssertionIDRef); DECL_TYPED_CHILDREN(AssertionURIRef); DECL_TYPED_CHILDREN(Assertion); - //DECL_TYPED_CHILDREN(EncryptedAssertion); + DECL_TYPED_CHILDREN(EncryptedAssertion); DECL_XMLOBJECT_CHILDREN(Other); /** AdviceType local name */ static const XMLCh TYPE_NAME[]; @@ -276,6 +306,9 @@ namespace opensaml { DECL_SAML2OBJECTBUILDER(AuthnStatement); DECL_SAML2OBJECTBUILDER(AuthzDecisionStatement); DECL_SAML2OBJECTBUILDER(Conditions); + DECL_SAML2OBJECTBUILDER(EncryptedAssertion); + DECL_SAML2OBJECTBUILDER(EncryptedAttribute); + DECL_SAML2OBJECTBUILDER(EncryptedID); DECL_SAML2OBJECTBUILDER(Evidence); DECL_SAML2OBJECTBUILDER(Issuer); DECL_SAML2OBJECTBUILDER(NameID); diff --git a/saml/saml2/core/impl/Assertions20Impl.cpp b/saml/saml2/core/impl/Assertions20Impl.cpp index 4152362..5d4e58f 100644 --- a/saml/saml2/core/impl/Assertions20Impl.cpp +++ b/saml/saml2/core/impl/Assertions20Impl.cpp @@ -22,12 +22,14 @@ #include "internal.h" #include "exceptions.h" +#include "saml/encryption/EncryptedKeyResolver.h" #include "saml2/core/Assertions.h" #include #include #include #include +#include #include #include #include @@ -39,6 +41,7 @@ using namespace opensaml::saml2; using namespace opensaml; +using namespace xmlencryption; using namespace xmlsignature; using namespace xmltooling; using namespace std; @@ -118,6 +121,7 @@ namespace opensaml { PROC_STRING_ATTRIB(SPNameQualifier,SPNAMEQUALIFIER,NULL); PROC_STRING_ATTRIB(Format,FORMAT,NULL); PROC_STRING_ATTRIB(SPProvidedID,SPPROVIDEDID,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; @@ -153,6 +157,91 @@ namespace opensaml { } }; + class SAML_DLLLOCAL EncryptedElementTypeImpl : public virtual EncryptedElementType, + public AbstractComplexElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + void init() { + m_EncryptedData=NULL; + m_children.push_back(NULL); + m_pos_EncryptedData=m_children.begin(); + } + + protected: + EncryptedElementTypeImpl() { + init(); + } + + public: + virtual ~EncryptedElementTypeImpl() {} + + EncryptedElementTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + EncryptedElementTypeImpl(const EncryptedElementTypeImpl& src) + : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) { + init(); + if (src.getEncryptedData()) + setEncryptedData(src.getEncryptedData()->cloneEncryptedData()); + VectorOf(EncryptedKey) v=getEncryptedKeys(); + for (vector::const_iterator i=src.m_EncryptedKeys.begin(); i!=src.m_EncryptedKeys.end(); i++) { + if (*i) { + v.push_back((*i)->cloneEncryptedKey()); + } + } + } + + XMLObject* decrypt(KeyResolver* KEKresolver, const XMLCh* recipient) const + { + if (!m_EncryptedData) + throw DecryptionException("No encrypted data present."); + Decrypter decrypter(KEKresolver, new EncryptedKeyResolver(*this, recipient)); + DOMDocumentFragment* frag = decrypter.decryptData(m_EncryptedData); + if (frag->hasChildNodes() && frag->getFirstChild()==frag->getLastChild()) { + DOMNode* plaintext=frag->getFirstChild(); + if (plaintext->getNodeType()==DOMNode::ELEMENT_NODE) { + auto_ptr ret(XMLObjectBuilder::buildOneFromElement(static_cast(plaintext))); + ret->releaseThisAndChildrenDOM(); + return ret.release(); + } + } + frag->release(); + throw DecryptionException("Decryption did not result in a single element."); + } + + IMPL_XMLOBJECT_CLONE(EncryptedElementType); + IMPL_TYPED_FOREIGN_CHILD(EncryptedData,xmlencryption); + IMPL_TYPED_FOREIGN_CHILDREN(EncryptedKey,xmlencryption,m_children.end()); + + protected: + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_FOREIGN_CHILD(EncryptedData,xmlencryption,XMLConstants::XMLENC_NS,false); + PROC_TYPED_FOREIGN_CHILDREN(EncryptedKey,xmlencryption,XMLConstants::XMLENC_NS,false); + AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); + } + }; + + class SAML_DLLLOCAL EncryptedIDImpl : public virtual EncryptedID, public EncryptedElementTypeImpl + { + public: + virtual ~EncryptedIDImpl() {} + + EncryptedIDImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) {} + + EncryptedIDImpl(const EncryptedIDImpl& src) : AbstractXMLObject(src), EncryptedElementTypeImpl(src) {} + + IMPL_XMLOBJECT_CLONE(EncryptedID); + EncryptedElementType* cloneEncryptedElementType() const { + return new EncryptedIDImpl(*this); + } + }; + class SAML_DLLLOCAL AudienceRestrictionImpl : public virtual AudienceRestriction, public AbstractComplexElement, public AbstractDOMCachingXMLObject, @@ -258,6 +347,7 @@ namespace opensaml { void processAttribute(const DOMAttr* attribute) { PROC_INTEGER_ATTRIB(Count,COUNT,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; @@ -343,6 +433,7 @@ namespace opensaml { void processAttribute(const DOMAttr* attribute) { PROC_DATETIME_ATTRIB(NotBefore,NOTBEFORE,NULL); PROC_DATETIME_ATTRIB(NotOnOrAfter,NOTONORAFTER,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; @@ -524,7 +615,7 @@ namespace opensaml { m_Method=NULL; m_BaseID=NULL; m_NameID=NULL; - //m_EncryptedID=NULL; + m_EncryptedID=NULL; m_SubjectConfirmationData=NULL; m_KeyInfoConfirmationDataType=NULL; m_children.push_back(NULL); @@ -534,7 +625,9 @@ namespace opensaml { m_pos_BaseID=m_children.begin(); m_pos_NameID=m_pos_BaseID; ++m_pos_NameID; - m_pos_SubjectConfirmationData=m_pos_NameID; + m_pos_EncryptedID=m_pos_NameID; + ++m_pos_EncryptedID; + m_pos_SubjectConfirmationData=m_pos_EncryptedID; ++m_pos_SubjectConfirmationData; m_pos_KeyInfoConfirmationDataType=m_pos_SubjectConfirmationData; ++m_pos_KeyInfoConfirmationDataType; @@ -557,8 +650,8 @@ namespace opensaml { setBaseID(src.getBaseID()->cloneBaseID()); if (src.getNameID()) setNameID(src.getNameID()->cloneNameID()); - //if (src.getEncryptedID()) - //setEncryptedID(src.getEncryptedID()->cloneEncryptedID()); + if (src.getEncryptedID()) + setEncryptedID(src.getEncryptedID()->cloneEncryptedID()); if (src.getSubjectConfirmationData()) setSubjectConfirmationData(src.getSubjectConfirmationData()->clone()); if (src.getKeyInfoConfirmationDataType()) @@ -569,7 +662,7 @@ namespace opensaml { IMPL_STRING_ATTRIB(Method); IMPL_TYPED_CHILD(BaseID); IMPL_TYPED_CHILD(NameID); - //IMPL_TYPED_CHILD(EncryptedID); + IMPL_TYPED_CHILD(EncryptedID); IMPL_XMLOBJECT_CHILD(SubjectConfirmationData); IMPL_TYPED_CHILD(KeyInfoConfirmationDataType); @@ -581,7 +674,7 @@ namespace opensaml { void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { PROC_TYPED_CHILD(BaseID,SAMLConstants::SAML20_NS,false); PROC_TYPED_CHILD(NameID,SAMLConstants::SAML20_NS,false); - //PROC_TYPED_CHILD(EncryptedID,SAMLConstants::SAML20_NS,false); + PROC_TYPED_CHILD(EncryptedID,SAMLConstants::SAML20_NS,false); PROC_XMLOBJECT_CHILD(SubjectConfirmationData,SAMLConstants::SAML20_NS); PROC_TYPED_CHILD(KeyInfoConfirmationDataType,SAMLConstants::SAML20_NS,false); AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); @@ -589,6 +682,7 @@ namespace opensaml { void processAttribute(const DOMAttr* attribute) { PROC_STRING_ATTRIB(Method,METHOD,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; @@ -609,8 +703,8 @@ namespace opensaml { m_pos_BaseID=m_children.begin(); m_pos_NameID=m_pos_BaseID; ++m_pos_NameID; - //m_pos_EncryptedID=m_pos_NameID; - //++m_pos_EncryptedID; + m_pos_EncryptedID=m_pos_NameID; + ++m_pos_EncryptedID; } public: virtual ~SubjectImpl() {} @@ -629,8 +723,8 @@ namespace opensaml { setBaseID(src.getBaseID()->cloneBaseID()); if (src.getNameID()) setNameID(src.getNameID()->cloneNameID()); - //if (src.getEncryptedID()) - //setEncryptedID(src.getEncryptedID()->cloneEncryptedID()); + if (src.getEncryptedID()) + setEncryptedID(src.getEncryptedID()->cloneEncryptedID()); VectorOf(SubjectConfirmation) v=getSubjectConfirmations(); for (vector::const_iterator i=src.m_SubjectConfirmations.begin(); i!=src.m_SubjectConfirmations.end(); i++) { if (*i) { @@ -642,14 +736,14 @@ namespace opensaml { IMPL_XMLOBJECT_CLONE(Subject); IMPL_TYPED_CHILD(NameID); IMPL_TYPED_CHILD(BaseID); - //IMPL_TYPED_CHILD(EncryptedID); + IMPL_TYPED_CHILD(EncryptedID); IMPL_TYPED_CHILDREN(SubjectConfirmation,m_children.end()); protected: void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { PROC_TYPED_CHILD(BaseID,SAMLConstants::SAML20_NS,false); PROC_TYPED_CHILD(NameID,SAMLConstants::SAML20_NS,false); - //PROC_TYPED_CHILD(EncryptedID,SAMLConstants::SAML20_NS,false); + PROC_TYPED_CHILD(EncryptedID,SAMLConstants::SAML20_NS,false); PROC_TYPED_CHILDREN(SubjectConfirmation,SAMLConstants::SAML20_NS,false); AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); } @@ -696,6 +790,7 @@ namespace opensaml { void processAttribute(const DOMAttr* attribute) { PROC_STRING_ATTRIB(Address,ADDRESS,NULL); PROC_STRING_ATTRIB(DNSName,DNSNAME,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; @@ -849,6 +944,7 @@ namespace opensaml { PROC_DATETIME_ATTRIB(AuthnInstant,AUTHNINSTANT,NULL); PROC_STRING_ATTRIB(SessionIndex,SESSIONINDEX,NULL); PROC_DATETIME_ATTRIB(SessionNotOnOrAfter,SESSIONNOTONORAFTER,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; @@ -887,6 +983,7 @@ namespace opensaml { void processAttribute(const DOMAttr* attribute) { PROC_STRING_ATTRIB(Namespace,NAMESPACE,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; @@ -1021,6 +1118,7 @@ namespace opensaml { void processAttribute(const DOMAttr* attribute) { PROC_STRING_ATTRIB(Resource,RESOURCE,NULL); PROC_STRING_ATTRIB(Decision,DECISION,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; @@ -1124,6 +1222,22 @@ namespace opensaml { } }; + class SAML_DLLLOCAL EncryptedAttributeImpl : public virtual EncryptedAttribute, public EncryptedElementTypeImpl + { + public: + virtual ~EncryptedAttributeImpl() {} + + EncryptedAttributeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) {} + + EncryptedAttributeImpl(const EncryptedAttributeImpl& src) : AbstractXMLObject(src), EncryptedElementTypeImpl(src) {} + + IMPL_XMLOBJECT_CLONE(EncryptedAttribute); + EncryptedElementType* cloneEncryptedElementType() const { + return new EncryptedAttributeImpl(*this); + } + }; + class SAML_DLLLOCAL AttributeStatementImpl : public virtual AttributeStatement, public AbstractComplexElement, public AbstractDOMCachingXMLObject, @@ -1150,13 +1264,11 @@ namespace opensaml { continue; } - /* EncryptedAttribute* enc=dynamic_cast(*i); if (enc) { getEncryptedAttributes().push_back(enc->cloneEncryptedAttribute()); continue; } - */ } } } @@ -1166,12 +1278,12 @@ namespace opensaml { return cloneAttributeStatement(); } IMPL_TYPED_CHILDREN(Attribute, m_children.end()); - //IMPL_TYPED_CHILDREN(EncryptedAttribute, m_children.end()); + IMPL_TYPED_CHILDREN(EncryptedAttribute, m_children.end()); protected: void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { PROC_TYPED_CHILDREN(Attribute,SAMLConstants::SAML20_NS,false); - //PROC_TYPED_CHILDREN(EncryptedAttribute,SAMLConstants::SAML20_NS,false); + PROC_TYPED_CHILDREN(EncryptedAttribute,SAMLConstants::SAML20_NS,false); AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); } }; @@ -1214,13 +1326,12 @@ namespace opensaml { continue; } - /* EncryptedAssertion* enc=dynamic_cast(*i); if (enc) { getEncryptedAssertions().push_back(enc->cloneEncryptedAssertion()); continue; } - */ + getOthers().push_back((*i)->clone()); } } @@ -1230,7 +1341,7 @@ namespace opensaml { IMPL_TYPED_CHILDREN(AssertionIDRef,m_children.end()); IMPL_TYPED_CHILDREN(AssertionURIRef,m_children.end()); IMPL_TYPED_CHILDREN(Assertion,m_children.end()); - //IMPL_TYPED_CHILDREN(EncryptedAssertion,m_children.end()); + IMPL_TYPED_CHILDREN(EncryptedAssertion,m_children.end()); IMPL_XMLOBJECT_CHILDREN(Other,m_children.end()); protected: @@ -1238,17 +1349,35 @@ namespace opensaml { PROC_TYPED_CHILDREN(AssertionIDRef,SAMLConstants::SAML20_NS,false); PROC_TYPED_CHILDREN(AssertionURIRef,SAMLConstants::SAML20_NS,false); PROC_TYPED_CHILDREN(Assertion,SAMLConstants::SAML20_NS,false); - //PROC_TYPED_CHILDREN(EncryptedAssertion,SAMLConstants::SAML20_NS,false); + PROC_TYPED_CHILDREN(EncryptedAssertion,SAMLConstants::SAML20_NS,false); // Unknown child. const XMLCh* nsURI=root->getNamespaceURI(); - if (!XMLString::equals(nsURI,SAMLConstants::SAML20_NS) && nsURI && *nsURI) + if (!XMLString::equals(nsURI,SAMLConstants::SAML20_NS) && nsURI && *nsURI) { getOthers().push_back(childXMLObject); + return; + } AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); } }; + class SAML_DLLLOCAL EncryptedAssertionImpl : public virtual EncryptedAssertion, public EncryptedElementTypeImpl + { + public: + virtual ~EncryptedAssertionImpl() {} + + EncryptedAssertionImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) {} + + EncryptedAssertionImpl(const EncryptedAssertionImpl& src) : AbstractXMLObject(src), EncryptedElementTypeImpl(src) {} + + IMPL_XMLOBJECT_CLONE(EncryptedAssertion); + EncryptedElementType* cloneEncryptedElementType() const { + return new EncryptedAssertionImpl(*this); + } + }; + class SAML_DLLLOCAL AssertionImpl : public virtual Assertion, public AbstractComplexElement, public AbstractDOMCachingXMLObject, @@ -1403,6 +1532,7 @@ namespace opensaml { PROC_STRING_ATTRIB(Version,VER,NULL); PROC_ID_ATTRIB(ID,ID,NULL); PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; @@ -1433,6 +1563,9 @@ IMPL_XMLOBJECTBUILDER(AuthnContextDeclRef); IMPL_XMLOBJECTBUILDER(AuthnStatement); IMPL_XMLOBJECTBUILDER(AuthzDecisionStatement); IMPL_XMLOBJECTBUILDER(Conditions); +IMPL_XMLOBJECTBUILDER(EncryptedAssertion); +IMPL_XMLOBJECTBUILDER(EncryptedAttribute); +IMPL_XMLOBJECTBUILDER(EncryptedID); IMPL_XMLOBJECTBUILDER(Evidence); IMPL_XMLOBJECTBUILDER(Issuer); IMPL_XMLOBJECTBUILDER(KeyInfoConfirmationDataType); @@ -1495,6 +1628,11 @@ const XMLCh Conditions::LOCAL_NAME[] = UNICODE_LITERAL_10(C,o,n,d,i const XMLCh Conditions::TYPE_NAME[] = UNICODE_LITERAL_14(C,o,n,d,i,t,i,o,n,s,T,y,p,e); const XMLCh Conditions::NOTBEFORE_ATTRIB_NAME[] = UNICODE_LITERAL_9(N,o,t,B,e,f,o,r,e); const XMLCh Conditions::NOTONORAFTER_ATTRIB_NAME[] =UNICODE_LITERAL_12(N,o,t,O,n,O,r,A,f,t,e,r); +const XMLCh EncryptedAssertion::LOCAL_NAME[] = UNICODE_LITERAL_18(E,n,c,r,y,p,t,e,d,A,s,s,e,r,t,i,o,n); +const XMLCh EncryptedAttribute::LOCAL_NAME[] = UNICODE_LITERAL_18(E,n,c,r,y,p,t,e,d,A,t,t,r,i,b,u,t,e); +const XMLCh EncryptedElementType::LOCAL_NAME[] = {chNull}; +const XMLCh EncryptedElementType::TYPE_NAME[] = UNICODE_LITERAL_20(E,n,c,r,y,p,t,e,d,E,l,e,m,e,n,t,T,y,p,e); +const XMLCh EncryptedID::LOCAL_NAME[] = UNICODE_LITERAL_11(E,n,c,r,y,p,t,e,d,I,d); const XMLCh Evidence::LOCAL_NAME[] = UNICODE_LITERAL_8(E,v,i,d,e,n,c,e); const XMLCh Evidence::TYPE_NAME[] = UNICODE_LITERAL_12(E,v,i,d,e,n,c,e,T,y,p,e); const XMLCh Issuer::LOCAL_NAME[] = UNICODE_LITERAL_6(I,s,s,u,e,r); diff --git a/saml/saml2/core/impl/Assertions20SchemaValidators.cpp b/saml/saml2/core/impl/Assertions20SchemaValidators.cpp index e839e69..703a109 100644 --- a/saml/saml2/core/impl/Assertions20SchemaValidators.cpp +++ b/saml/saml2/core/impl/Assertions20SchemaValidators.cpp @@ -43,6 +43,22 @@ namespace opensaml { XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,NameID); XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,Issuer); + BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,EncryptedElementType); + XMLOBJECTVALIDATOR_REQUIRE(EncryptedElementType,EncryptedData); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR_SUB(SAML_DLLLOCAL,EncryptedID,EncryptedElementType); + EncryptedElementTypeSchemaValidator::validate(xmlObject); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR_SUB(SAML_DLLLOCAL,EncryptedAttribute,EncryptedElementType); + EncryptedElementTypeSchemaValidator::validate(xmlObject); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR_SUB(SAML_DLLLOCAL,EncryptedAssertion,EncryptedElementType); + EncryptedElementTypeSchemaValidator::validate(xmlObject); + END_XMLOBJECTVALIDATOR; + BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AudienceRestriction); XMLOBJECTVALIDATOR_NONEMPTY(AudienceRestriction,Audience); END_XMLOBJECTVALIDATOR; @@ -70,8 +86,8 @@ namespace opensaml { count++; if (ptr->getNameID()) count++; - //if (ptr->getEncryptedID()) - //count++; + if (ptr->getEncryptedID()) + count++; if (count > 1) throw ValidationException("SubjectConfirmation cannot contain multiple identifier elements."); END_XMLOBJECTVALIDATOR; @@ -82,8 +98,8 @@ namespace opensaml { count++; if (ptr->getNameID()) count++; - //if (ptr->getEncryptedID()) - //count++; + if (ptr->getEncryptedID()) + count++; if (count > 1) throw ValidationException("Subject cannot contain multiple identifier elements."); END_XMLOBJECTVALIDATOR; @@ -196,6 +212,9 @@ void opensaml::saml2::registerAssertionClasses() { REGISTER_ELEMENT(AuthnStatement); REGISTER_ELEMENT(AuthzDecisionStatement); REGISTER_ELEMENT(Conditions); + REGISTER_ELEMENT(EncryptedAssertion); + REGISTER_ELEMENT(EncryptedAttribute); + REGISTER_ELEMENT(EncryptedID); REGISTER_ELEMENT(Evidence); REGISTER_ELEMENT(Issuer); REGISTER_ELEMENT(NameID);