Major revamp of credential and trust handling code, PKIX engine still needs work.
[shibboleth/cpp-xmltooling.git] / xmltooling / signature / impl / XMLSecSignatureImpl.cpp
index 6199613..51a5119 100644 (file)
@@ -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.
@@ -23,6 +23,7 @@
 #include "internal.h"
 #include "exceptions.h"
 #include "impl/UnknownElement.h"
+#include "security/Credential.h"
 #include "signature/KeyInfo.h"
 #include "signature/Signature.h"
 #include "util/NDC.h"
@@ -75,8 +76,8 @@ namespace xmlsignature {
         XMLObject* clone() const;
         Signature* cloneSignature() const;
 
-        DOMElement* marshall(DOMDocument* document=NULL, const vector<Signature*>* sigs=NULL) const;
-        DOMElement* marshall(DOMElement* parentElement, const vector<Signature*>* sigs=NULL) const;
+        DOMElement* marshall(DOMDocument* document=NULL, const vector<Signature*>* sigs=NULL, const Credential* credential=NULL) const;
+        DOMElement* marshall(DOMElement* parentElement, const vector<Signature*>* sigs=NULL, const Credential* credential=NULL) const;
         XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);
         
         // Getters
@@ -102,14 +103,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;
         XSECCryptoKey* m_key;
-        KeyInfo* m_keyInfo;
+        mutable KeyInfo* m_keyInfo;
         ContentReference* m_reference;
     };
     
@@ -171,18 +172,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 +194,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 +206,13 @@ void XMLSecSignatureImpl::sign()
     }
 }
 
-DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Signature*>* sigs) const
+DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Signature*>* 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();
@@ -285,6 +288,13 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Si
     }
     
     // Marshall KeyInfo data.
+    if (credential) {
+        delete m_keyInfo;
+        m_keyInfo = NULL;
+        const KeyInfo* fromcred = credential->getKeyInfo();
+        if (fromcred)
+            m_keyInfo = fromcred->cloneKeyInfo();
+    }
     if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {
         m_keyInfo->marshall(cachedDOM);
     }
@@ -298,13 +308,13 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Si
     return cachedDOM;
 }
 
-DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vector<Signature*>* sigs) const
+DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vector<Signature*>* 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();
@@ -364,6 +374,13 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto
     }
 
     // Marshall KeyInfo data.
+    if (credential) {
+        delete m_keyInfo;
+        m_keyInfo = NULL;
+        const KeyInfo* fromcred = credential->getKeyInfo();
+        if (fromcred)
+            m_keyInfo = fromcred->cloneKeyInfo();
+    }
     if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {
         m_keyInfo->marshall(cachedDOM);
     }
@@ -379,7 +396,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 +416,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
 {