Update copyright.
[shibboleth/cpp-xmltooling.git] / xmltooling / signature / impl / XMLSecSignatureImpl.cpp
index 30bc1dc..a2a8cf8 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.
 #include <xsec/dsig/DSIGKeyInfoX509.hpp>
 #include <xsec/dsig/DSIGReference.hpp>
 #include <xsec/enc/XSECCryptoException.hpp>
+#include <xsec/framework/XSECAlgorithmHandler.hpp>
+#include <xsec/framework/XSECAlgorithmMapper.hpp>
 #include <xsec/framework/XSECException.hpp>
+#include <xsec/transformers/TXFMSB.hpp>
+#include <xsec/transformers/TXFMChain.hpp>
+#include <xsec/transformers/TXFMOutputFile.hpp>
 
 using namespace xmlsignature;
 using namespace xmltooling;
@@ -204,7 +209,7 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Si
     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();
@@ -299,7 +304,7 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto
     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();
@@ -374,7 +379,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(
@@ -403,9 +408,92 @@ Signature* SignatureBuilder::buildObject(
     return buildObject();
 }
 
-Signature* SignatureBuilder::buildObject() const
+#ifdef HAVE_COVARIANT_RETURNS
+Signature*
+#else
+XMLObject*
+#endif
+SignatureBuilder::buildObject() const
 {
     return new XMLSecSignatureImpl();
 }
 
 const XMLCh Signature::LOCAL_NAME[] = UNICODE_LITERAL_9(S,i,g,n,a,t,u,r,e);
+
+// Raw signature methods.
+
+unsigned int Signature::createRawSignature(
+    XSECCryptoKey* key, const XMLCh* sigAlgorithm, const char* in, unsigned int in_len, char* out, unsigned int out_len
+    )
+{
+    try {
+        XSECAlgorithmHandler* handler = XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(sigAlgorithm);
+        if (!handler) {
+            auto_ptr_char alg(sigAlgorithm);
+            throw SignatureException("Unsupported signature algorithm ($1).", params(1,alg.get()));
+        }
+        
+        // Move input into a safeBuffer to source the transform chain.
+        safeBuffer sb,sbout;
+        sb.sbStrncpyIn(in,in_len);
+        TXFMSB* sbt = new TXFMSB(NULL);
+        sbt->setInput(sb, in_len);
+        TXFMChain tx(sbt);
+        
+        // Sign the chain.
+        unsigned int siglen = handler->signToSafeBuffer(&tx, sigAlgorithm, key, out_len-1, sbout);
+        if (siglen >= out_len)
+            throw SignatureException("Signature size exceeded output buffer size.");
+        
+        // Push all non-whitespace into buffer.
+        unsigned int ret_len = 0;
+        const char* source = sbout.rawCharBuffer();
+        while (siglen--) {
+            if (isspace(*source))
+                ++source;
+            else {
+                *out++ = *source++;
+                ++ret_len;
+            }
+        }
+        *out = 0;
+        return ret_len;
+    }
+    catch(XSECException& e) {
+        auto_ptr_char temp(e.getMsg());
+        throw SignatureException(string("Caught an XMLSecurity exception while creating raw signature: ") + temp.get());
+    }
+    catch(XSECCryptoException& e) {
+        throw SignatureException(string("Caught an XMLSecurity exception while creating raw signature: ") + e.getMsg());
+    }
+}
+
+bool Signature::verifyRawSignature(
+    XSECCryptoKey* key, const XMLCh* sigAlgorithm, const char* signature, const char* in, unsigned int in_len
+    )
+{
+    try {
+        XSECAlgorithmHandler* handler = XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(sigAlgorithm);
+        if (!handler) {
+            auto_ptr_char alg(sigAlgorithm);
+            throw SignatureException("Unsupported signature algorithm ($1).", params(1,alg.get()));
+        }
+        
+        // Move input into a safeBuffer to source the transform chain.
+        safeBuffer sb;
+        sb.sbStrncpyIn(in,in_len);
+        TXFMSB* sbt = new TXFMSB(NULL);
+        sbt->setInput(sb, in_len);
+        TXFMChain tx(sbt);
+        
+        // Verify the chain.
+        return handler->verifyBase64Signature(&tx, sigAlgorithm, signature, 0, key);
+    }
+    catch(XSECException& e) {
+        auto_ptr_char temp(e.getMsg());
+        throw SignatureException(string("Caught an XMLSecurity exception while verifying raw signature: ") + temp.get());
+    }
+    catch(XSECCryptoException& e) {
+        throw SignatureException(string("Caught an XMLSecurity exception while verifying raw signature: ") + e.getMsg());
+    }
+}