X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=xmltooling%2Fsignature%2Fimpl%2FXMLSecSignatureImpl.cpp;h=dec07c1bf651daeaa059bd383be4d48aadfede24;hb=83de10b45721b7882182aaa8a6df0c729db8fc01;hp=61996139018ce32f6a271ddcbddb68be89107e63;hpb=36769dc1d8419136e55dde51697b47683b376214;p=shibboleth%2Fcpp-xmltooling.git diff --git a/xmltooling/signature/impl/XMLSecSignatureImpl.cpp b/xmltooling/signature/impl/XMLSecSignatureImpl.cpp index 6199613..dec07c1 100644 --- a/xmltooling/signature/impl/XMLSecSignatureImpl.cpp +++ b/xmltooling/signature/impl/XMLSecSignatureImpl.cpp @@ -1,5 +1,5 @@ /* -* Copyright 2001-2006 Internet2 +* Copyright 2001-2009 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,14 +22,16 @@ #include "internal.h" #include "exceptions.h" +#include "logging.h" #include "impl/UnknownElement.h" +#include "security/Credential.h" +#include "signature/ContentReference.h" #include "signature/KeyInfo.h" #include "signature/Signature.h" #include "util/NDC.h" #include "util/XMLConstants.h" #include "util/XMLHelper.h" -#include #include #include #include @@ -44,23 +46,25 @@ #include using namespace xmlsignature; +using namespace xmltooling::logging; using namespace xmltooling; -using namespace log4cpp; +using namespace xercesc; using namespace std; using xmlconstants::XMLSIG_NS; using xmlconstants::XMLSIG_PREFIX; +namespace xmlsignature { + #if defined (_MSC_VER) #pragma warning( push ) #pragma warning( disable : 4250 4251 ) #endif - -namespace xmlsignature { class XMLTOOL_DLLLOCAL XMLSecSignatureImpl : public UnknownElementImpl, public virtual Signature { public: - XMLSecSignatureImpl() : UnknownElementImpl(XMLSIG_NS, Signature::LOCAL_NAME, XMLSIG_PREFIX), + XMLSecSignatureImpl() : AbstractXMLObject(XMLSIG_NS, Signature::LOCAL_NAME, XMLSIG_PREFIX), + UnknownElementImpl(XMLSIG_NS, Signature::LOCAL_NAME, XMLSIG_PREFIX), m_signature(NULL), m_c14n(NULL), m_sm(NULL), m_key(NULL), m_keyInfo(NULL), m_reference(NULL) {} virtual ~XMLSecSignatureImpl(); @@ -75,13 +79,29 @@ namespace xmlsignature { XMLObject* clone() const; Signature* cloneSignature() const; - DOMElement* marshall(DOMDocument* document=NULL, const vector* sigs=NULL) const; - DOMElement* marshall(DOMElement* parentElement, const vector* sigs=NULL) const; + DOMElement* marshall(DOMDocument* document=NULL, const vector* sigs=NULL, const Credential* credential=NULL) const; + DOMElement* marshall(DOMElement* parentElement, const vector* sigs=NULL, const Credential* credential=NULL) const; XMLObject* unmarshall(DOMElement* element, bool bindDocument=false); // Getters - const XMLCh* getCanonicalizationMethod() const { return m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC; } - const XMLCh* getSignatureAlgorithm() const { return m_sm ? m_sm : DSIGConstants::s_unicodeStrURIRSA_SHA1; } + const XMLCh* getCanonicalizationMethod() const { + if (m_signature) + return canonicalizationMethod2UNICODEURI(m_signature->getCanonicalizationMethod()); + return m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC; + } + const XMLCh* getSignatureAlgorithm() const { + if (!m_sm && m_signature) { +#ifdef XMLTOOLING_XMLSEC_SIGALGORITHM + m_sm = XMLString::replicate(m_signature->getAlgorithmURI()); +#else + safeBuffer sURI; + if (signatureHashMethod2URI(sURI, m_signature->getSignatureMethod(), m_signature->getHashMethod())) + m_sm = XMLString::replicate(sURI.sbStrToXMLCh()); +#endif + } + return m_sm; + } + KeyInfo* getKeyInfo() const { return m_keyInfo; } ContentReference* getContentReference() const { return m_reference; } DSIGSignature* getXMLSignature() const { return m_signature; } @@ -102,22 +122,37 @@ namespace xmlsignature { m_reference=reference; } - void sign(); + void sign(const Credential* credential=NULL); private: mutable DSIGSignature* m_signature; XMLCh* m_c14n; - XMLCh* m_sm; + mutable XMLCh* m_sm; XSECCryptoKey* m_key; - KeyInfo* m_keyInfo; + mutable KeyInfo* m_keyInfo; ContentReference* m_reference; }; - -}; #if defined (_MSC_VER) #pragma warning( pop ) #endif +}; + +ContentReference::ContentReference() +{ +} + +ContentReference::~ContentReference() +{ +} + +Signature::Signature() +{ +} + +Signature::~Signature() +{ +} XMLSecSignatureImpl::~XMLSecSignatureImpl() { @@ -171,18 +206,20 @@ Signature* XMLSecSignatureImpl::cloneSignature() const return ret; } -void XMLSecSignatureImpl::sign() +void XMLSecSignatureImpl::sign(const Credential* credential) { Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature"); log.debug("applying signature"); if (!m_signature) throw SignatureException("Only a marshalled Signature object can be signed."); - else if (!m_key) - throw SignatureException("No signing key available for signature creation."); else if (!m_reference) throw SignatureException("No ContentReference object set for signature creation."); + XSECCryptoKey* key = credential ? credential->getPrivateKey() : m_key; + if (!key) + throw SignatureException("No signing key available for signature creation."); + try { log.debug("creating signature reference(s)"); DSIGReferenceList* refs = m_signature->getReferenceList(); @@ -191,7 +228,7 @@ void XMLSecSignatureImpl::sign() m_reference->createReferences(m_signature); log.debug("computing signature"); - m_signature->setSigningKey(m_key->clone()); + m_signature->setSigningKey(key->clone()); m_signature->sign(); } catch(XSECException& e) { @@ -203,13 +240,13 @@ void XMLSecSignatureImpl::sign() } } -DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector* sigs) const +DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector* sigs, const Credential* credential) const { #ifdef _DEBUG xmltooling::NDC ndc("marshall"); #endif - Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature"); + Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLObject.Signature"); log.debug("marshalling ds:Signature"); DOMElement* cachedDOM=getDOM(); @@ -240,9 +277,13 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vectorcreateDocument(); bindDocument=true; } - m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature(); - m_signature->setDSIGNSPrefix(XMLSIG_PREFIX); - cachedDOM=m_signature->createBlankSignature(document, getCanonicalizationMethod(), getSignatureAlgorithm()); + DSIGSignature* temp=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature(); + temp->setDSIGNSPrefix(XMLSIG_PREFIX); + const XMLCh* alg = getSignatureAlgorithm(); + if (!alg) + alg = DSIGConstants::s_unicodeStrURIRSA_SHA1; + cachedDOM=temp->createBlankSignature(document, getCanonicalizationMethod(), alg); + m_signature = temp; } else { // We need to reparse the XML we saved off into a new DOM. @@ -285,6 +326,11 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vectorgetKeyInfo(); + } if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) { m_keyInfo->marshall(cachedDOM); } @@ -298,13 +344,13 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector* sigs) const +DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vector* sigs, const Credential* credential) const { #ifdef _DEBUG xmltooling::NDC ndc("marshall"); #endif - Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature"); + Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLObject.Signature"); log.debug("marshalling ds:Signature"); DOMElement* cachedDOM=getDOM(); @@ -331,11 +377,13 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto if (m_xml.empty()) { // Fresh signature, so we just create an empty one. log.debug("creating empty Signature element"); - m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature(); - m_signature->setDSIGNSPrefix(XMLSIG_PREFIX); - cachedDOM=m_signature->createBlankSignature( - parentElement->getOwnerDocument(), getCanonicalizationMethod(), getSignatureAlgorithm() - ); + DSIGSignature* temp=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature(); + temp->setDSIGNSPrefix(XMLSIG_PREFIX); + const XMLCh* alg = getSignatureAlgorithm(); + if (!alg) + alg = DSIGConstants::s_unicodeStrURIRSA_SHA1; + cachedDOM=temp->createBlankSignature(parentElement->getOwnerDocument(), getCanonicalizationMethod(), alg); + m_signature = temp; } else { MemBufInputSource src(reinterpret_cast(m_xml.c_str()),m_xml.length(),"XMLSecSignatureImpl"); @@ -364,6 +412,11 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto } // Marshall KeyInfo data. + if (credential) { + delete m_keyInfo; + m_keyInfo = NULL; + m_keyInfo = credential->getKeyInfo(); + } if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) { m_keyInfo->marshall(cachedDOM); } @@ -379,7 +432,7 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto XMLObject* XMLSecSignatureImpl::unmarshall(DOMElement* element, bool bindDocument) { - Category::getInstance(XMLTOOLING_LOGCAT".Signature").debug("unmarshalling ds:Signature"); + Category::getInstance(XMLTOOLING_LOGCAT".XMLObject.Signature").debug("unmarshalling ds:Signature"); try { m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM( @@ -399,8 +452,13 @@ XMLObject* XMLSecSignatureImpl::unmarshall(DOMElement* element, bool bindDocumen return this; } -Signature* SignatureBuilder::buildObject( - const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType +#ifdef HAVE_COVARIANT_RETURNS +Signature* +#else +XMLObject* +#endif +SignatureBuilder::buildObject( + const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType ) const { if (!XMLString::equals(nsURI,XMLSIG_NS) || !XMLString::equals(localName,Signature::LOCAL_NAME)) @@ -418,6 +476,20 @@ SignatureBuilder::buildObject() const return new XMLSecSignatureImpl(); } +Signature* SignatureBuilder::buildSignature() { + const SignatureBuilder* b = dynamic_cast( + XMLObjectBuilder::getBuilder(xmltooling::QName(xmlconstants::XMLSIG_NS,Signature::LOCAL_NAME)) + ); + if (b) { +#ifdef HAVE_COVARIANT_RETURNS + return b->buildObject(); +#else + return dynamic_cast(b->buildObject()); +#endif + } + throw XMLObjectException("Unable to obtain typed builder for Signature."); +} + const XMLCh Signature::LOCAL_NAME[] = UNICODE_LITERAL_9(S,i,g,n,a,t,u,r,e); // Raw signature methods.