X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=xmltooling%2Fsignature%2Fimpl%2FXMLSecSignatureImpl.cpp;h=938a68480c603b67f6ee5cef0dc3cd6e7b9c32b9;hb=64dcaec957e9befd960779498d7fe35bbb62141a;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..938a684 100644 --- a/xmltooling/signature/impl/XMLSecSignatureImpl.cpp +++ b/xmltooling/signature/impl/XMLSecSignatureImpl.cpp @@ -1,5 +1,5 @@ /* -* Copyright 2001-2006 Internet2 +* Copyright 2001-2007 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,15 @@ #include "internal.h" #include "exceptions.h" +#include "logging.h" #include "impl/UnknownElement.h" +#include "security/Credential.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,8 +45,8 @@ #include using namespace xmlsignature; +using namespace xmltooling::logging; using namespace xmltooling; -using namespace log4cpp; using namespace std; using xmlconstants::XMLSIG_NS; using xmlconstants::XMLSIG_PREFIX; @@ -60,7 +61,8 @@ 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 +77,26 @@ 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) { + safeBuffer sURI; + if (signatureHashMethod2URI(sURI, m_signature->getSignatureMethod(), m_signature->getHashMethod()) == false) + return NULL; + m_sm = XMLString::replicate(sURI.sbStrToXMLCh()); + } + return m_sm ? m_sm : DSIGConstants::s_unicodeStrURIRSA_SHA1; + } + KeyInfo* getKeyInfo() const { return m_keyInfo; } ContentReference* getContentReference() const { return m_reference; } DSIGSignature* getXMLSignature() const { return m_signature; } @@ -102,14 +117,14 @@ 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; }; @@ -171,18 +186,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 +208,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 +220,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 +257,10 @@ 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); + cachedDOM=temp->createBlankSignature(document, getCanonicalizationMethod(), getSignatureAlgorithm()); + m_signature = temp; } else { // We need to reparse the XML we saved off into a new DOM. @@ -285,6 +303,11 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vectorgetKeyInfo(); + } if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) { m_keyInfo->marshall(cachedDOM); } @@ -298,13 +321,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 +354,10 @@ 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); + cachedDOM=temp->createBlankSignature(parentElement->getOwnerDocument(), getCanonicalizationMethod(), getSignatureAlgorithm()); + m_signature = temp; } else { MemBufInputSource src(reinterpret_cast(m_xml.c_str()),m_xml.length(),"XMLSecSignatureImpl"); @@ -364,6 +386,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 +406,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,7 +426,12 @@ XMLObject* XMLSecSignatureImpl::unmarshall(DOMElement* element, bool bindDocumen return this; } -Signature* SignatureBuilder::buildObject( +#ifdef HAVE_COVARIANT_RETURNS +Signature* +#else +XMLObject* +#endif +SignatureBuilder::buildObject( const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType ) const { @@ -497,3 +529,18 @@ bool Signature::verifyRawSignature( throw SignatureException(string("Caught an XMLSecurity exception while verifying raw signature: ") + e.getMsg()); } } + +void Signature::extractNames(DSIGKeyInfoList* keyInfo, set& names) +{ + char* kn; + const XMLCh* n; + + for (size_t s=0; sgetSize(); s++) { + n=keyInfo->item(s)->getKeyName(); + if (n && *n) { + kn=toUTF8(n); + names.insert(kn); + delete[] kn; + } + } +}