mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-09-28 19:05:55 +08:00
331 lines
7.9 KiB
C++
331 lines
7.9 KiB
C++
// ============================================================================
|
|
//
|
|
// = LIBRARY
|
|
// ulib - c++ library
|
|
//
|
|
// = FILENAME
|
|
// transform.cpp - xml Digital SIGnature with libxml2
|
|
//
|
|
// = AUTHOR
|
|
// Stefano Casazza
|
|
//
|
|
// ============================================================================
|
|
|
|
#include <ulib/utility/base64.h>
|
|
#include <ulib/utility/services.h>
|
|
|
|
#include "xpath.h"
|
|
|
|
// the allowed transforms usages
|
|
// the transform's name
|
|
// the transform's identification string (href)
|
|
|
|
int UTranformBase64::_usage = DSIG;
|
|
const char* UTranformBase64::_name = "base64";
|
|
const char* UTranformBase64::_href = "http://www.w3.org/2000/09/xmldsig#base64";
|
|
|
|
int UTranformInputURI::_usage = DSIG;
|
|
const char* UTranformInputURI::_name = "input-uri";
|
|
const char* UTranformInputURI::_href = "";
|
|
|
|
UVector<UIOCallback*>* UTranformInputURI::allIOCallbacks;
|
|
|
|
int UTranformInclC14N::_usage = DSIG|C14N;
|
|
const char* UTranformInclC14N::_name = "c14n";
|
|
const char* UTranformInclC14N::_href = "http://www.w3.org/2006/12/xml-c14n11"; // "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
|
|
|
|
int UTranformXPointer::_usage = DSIG;
|
|
const char* UTranformXPointer::_name = "xpointer";
|
|
const char* UTranformXPointer::_href = "http://www.w3.org/2001/04/xmldsig-more/xptr";
|
|
|
|
UXML2Document* UTranformXPointer::document;
|
|
|
|
int UTranformSha1::_usage = DIGEST;
|
|
const char* UTranformSha1::_name = "sha1";
|
|
const char* UTranformSha1::_href = "http://www.w3.org/2001/04/xmlenc#sha1";
|
|
|
|
int UTranformSha256::_usage = DIGEST;
|
|
const char* UTranformSha256::_name = "sha256";
|
|
const char* UTranformSha256::_href = "http://www.w3.org/2001/04/xmlenc#sha256";
|
|
|
|
int UTranformRsaMd5::_usage = SIGNATURE;
|
|
const char* UTranformRsaMd5::_name = "rsa-md5";
|
|
const char* UTranformRsaMd5::_href = "http://www.w3.org/2001/04/xmldsig-more#rsa-md5";
|
|
|
|
int UTranformRsaSha1::_usage = SIGNATURE;
|
|
const char* UTranformRsaSha1::_name = "rsa-sha1";
|
|
const char* UTranformRsaSha1::_href = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha1";
|
|
|
|
int UTranformRsaSha256::_usage = SIGNATURE;
|
|
const char* UTranformRsaSha256::_name = "rsa-sha256";
|
|
const char* UTranformRsaSha256::_href = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
|
|
|
|
UTranformXPointer::~UTranformXPointer()
|
|
{
|
|
U_TRACE_DTOR(0, UTranformXPointer)
|
|
|
|
dataList.clear();
|
|
}
|
|
|
|
UBaseTransform::UBaseTransform()
|
|
{
|
|
U_TRACE_CTOR(0, UBaseTransform, "")
|
|
|
|
status = 0;
|
|
hereNode = U_NULLPTR;
|
|
operation = 0;
|
|
}
|
|
|
|
UBaseTransform::~UBaseTransform()
|
|
{
|
|
U_TRACE_DTOR(0, UBaseTransform)
|
|
}
|
|
|
|
bool UTranformXPointer::setExpr(const char* expr, int nodeSetType, xmlNodePtr node)
|
|
{
|
|
U_TRACE(0, "UTranformXPointer::setExpr(%S,%d,%p)", expr, nodeSetType, node)
|
|
|
|
UBaseTransform::hereNode = node;
|
|
|
|
UXPathData* data;
|
|
|
|
U_NEW(UXPathData, data, UXPathData(UXPathData::XPOINTER, nodeSetType, expr));
|
|
|
|
if (data->registerNamespaces(node))
|
|
{
|
|
dataList.push(data);
|
|
|
|
U_RETURN(true);
|
|
}
|
|
|
|
U_DELETE(data)
|
|
|
|
U_RETURN(false);
|
|
}
|
|
|
|
// Opens the given @uri for reading
|
|
|
|
UTranformInputURI::UTranformInputURI(const char* uri)
|
|
{
|
|
U_TRACE_CTOR(0, UTranformInputURI, "%S", uri)
|
|
|
|
clbks = U_NULLPTR;
|
|
clbksCtx = U_NULLPTR;
|
|
|
|
/*
|
|
* Try to find one of the input accept method accepting that scheme
|
|
* Go in reverse to give precedence to user defined handlers.
|
|
* try with an unescaped version of the uri
|
|
*/
|
|
|
|
char* unescaped = U_SYSCALL(xmlURIUnescapeString, "%S,%d,%S", uri, 0, U_NULLPTR);
|
|
|
|
if (unescaped != U_NULLPTR)
|
|
{
|
|
clbks = find(unescaped);
|
|
|
|
if (clbks) clbksCtx = clbks->opencallback(unescaped);
|
|
|
|
U_SYSCALL_VOID(xmlFree, "%p", unescaped);
|
|
}
|
|
|
|
// If this failed try with a non-escaped uri this may be a strange filename
|
|
|
|
if (clbks == U_NULLPTR)
|
|
{
|
|
clbks = find(uri);
|
|
|
|
if (clbks) clbksCtx = clbks->opencallback(uri);
|
|
}
|
|
}
|
|
|
|
UIOCallback* UTranformInputURI::find(const char* uri)
|
|
{
|
|
U_TRACE(0, "UTranformInputURI::find(%S)", uri)
|
|
|
|
U_INTERNAL_ASSERT_POINTER(allIOCallbacks)
|
|
|
|
UIOCallback* callbacks;
|
|
|
|
for (uint32_t i = 0, n = allIOCallbacks->size(); i < n; ++i)
|
|
{
|
|
callbacks = (*allIOCallbacks)[i];
|
|
|
|
if (callbacks->matchcallback(uri)) U_RETURN_POINTER(callbacks, UIOCallback);
|
|
}
|
|
|
|
U_RETURN_POINTER(U_NULLPTR, UIOCallback);
|
|
}
|
|
|
|
/**
|
|
* Process binary @data by calling transform's execute method and pushes
|
|
* results to next transform.
|
|
*
|
|
* Returns: true on success or a false value if an error occurs.
|
|
*/
|
|
|
|
bool UTranformBase64::execute(UString& data)
|
|
{
|
|
U_TRACE(0, "UTranformBase64::execute(%.*S)", U_STRING_TO_TRACE(data))
|
|
|
|
UString buffer(data.size());
|
|
|
|
UBase64::decode(data, buffer);
|
|
|
|
if (buffer)
|
|
{
|
|
data = buffer;
|
|
|
|
U_RETURN(true);
|
|
}
|
|
|
|
U_RETURN(false);
|
|
}
|
|
|
|
bool UTranformInclC14N::execute(UString& data)
|
|
{
|
|
U_TRACE(0, "UTranformInclC14N::execute(%.*S)", U_STRING_TO_TRACE(data))
|
|
|
|
data = UXML2Document::xmlC14N(data);
|
|
|
|
U_RETURN(true);
|
|
}
|
|
|
|
bool UTranformSha1::execute(UString& data)
|
|
{
|
|
U_TRACE(0, "UTranformSha1::execute(%.*S)", U_STRING_TO_TRACE(data))
|
|
|
|
UString ObjectDigestValue(200U);
|
|
|
|
UServices::generateDigest(U_HASH_SHA1, 0, data, ObjectDigestValue, true);
|
|
|
|
data = ObjectDigestValue;
|
|
|
|
U_RETURN(true);
|
|
}
|
|
|
|
bool UTranformSha256::execute(UString& data)
|
|
{
|
|
U_TRACE(0, "UTranformSha256::execute(%.*S)", U_STRING_TO_TRACE(data))
|
|
|
|
UString ObjectDigestValue(200U);
|
|
|
|
UServices::generateDigest(U_HASH_SHA256, 0, data, ObjectDigestValue, true);
|
|
|
|
data = ObjectDigestValue;
|
|
|
|
U_RETURN(true);
|
|
}
|
|
|
|
bool UTranformRsaMd5::execute(UString& data)
|
|
{
|
|
U_TRACE(0, "UTranformRsaMd5::execute(%.*S)", U_STRING_TO_TRACE(data))
|
|
|
|
U_RETURN(false);
|
|
}
|
|
|
|
bool UTranformRsaSha1::execute(UString& data)
|
|
{
|
|
U_TRACE(0, "UTranformRsaSha1::execute(%.*S)", U_STRING_TO_TRACE(data))
|
|
|
|
U_RETURN(false);
|
|
}
|
|
|
|
bool UTranformRsaSha256::execute(UString& data)
|
|
{
|
|
U_TRACE(0, "UTranformRsaSha256::execute(%.*S)", U_STRING_TO_TRACE(data))
|
|
|
|
U_RETURN(false);
|
|
}
|
|
|
|
bool UTranformXPointer::execute(UString& data)
|
|
{
|
|
U_TRACE(0, "UTranformXPointer::execute(%.*S)", U_STRING_TO_TRACE(data))
|
|
|
|
U_INTERNAL_DUMP("dataList.size() = %u", dataList.size())
|
|
|
|
if (tag.empty())
|
|
{
|
|
UXPathData* pdata = dataList[0];
|
|
|
|
xmlXPathObjectPtr xpathObj = (xmlXPathObjectPtr) U_SYSCALL(xmlXPtrEval, "%S,%p", (const xmlChar*)pdata->expr, pdata->ctx);
|
|
|
|
if (xpathObj == U_NULLPTR) U_RETURN(false);
|
|
|
|
// ...
|
|
}
|
|
else
|
|
{
|
|
U_INTERNAL_ASSERT_POINTER(document)
|
|
|
|
(void) document->getElement(data, 128, U_STRING_TO_PARAM(tag));
|
|
}
|
|
|
|
U_RETURN(true);
|
|
}
|
|
|
|
bool UTranformInputURI::execute(UString& data)
|
|
{
|
|
U_TRACE(0, "UTranformInputURI::execute(%.*S)", U_STRING_TO_TRACE(data))
|
|
|
|
U_INTERNAL_DUMP("clbksCtx = %p clbks = %p", clbksCtx, clbks)
|
|
|
|
if (clbksCtx &&
|
|
clbks)
|
|
{
|
|
data.setBuffer(128 * 1024);
|
|
|
|
int ret = (clbks->readcallback)( clbksCtx, (char*)data.data(), (int)data.capacity());
|
|
(clbks->closecallback)(clbksCtx);
|
|
|
|
if (ret > 0)
|
|
{
|
|
data.size_adjust(ret);
|
|
|
|
U_RETURN(true);
|
|
}
|
|
}
|
|
|
|
U_RETURN(false);
|
|
}
|
|
|
|
// DEBUG
|
|
|
|
#ifdef DEBUG
|
|
# include <ulib/internal/objectIO.h>
|
|
|
|
const char* UBaseTransform::dump(bool reset) const
|
|
{
|
|
*UObjectIO::os << "status " << status << '\n'
|
|
<< "hereNode " << hereNode << '\n'
|
|
<< "operation " << operation;
|
|
|
|
if (reset)
|
|
{
|
|
UObjectIO::output();
|
|
|
|
return UObjectIO::buffer_output;
|
|
}
|
|
|
|
return U_NULLPTR;
|
|
}
|
|
|
|
const char* UIOCallback::dump(bool reset) const
|
|
{
|
|
*UObjectIO::os << "opencallback " << (void*)opencallback << '\n'
|
|
<< "readcallback " << (void*)readcallback << '\n'
|
|
<< "closecallback " << (void*)closecallback << '\n'
|
|
<< "matchcallback " << (void*)matchcallback;
|
|
|
|
if (reset)
|
|
{
|
|
UObjectIO::output();
|
|
|
|
return UObjectIO::buffer_output;
|
|
}
|
|
|
|
return U_NULLPTR;
|
|
}
|
|
|
|
#endif
|